Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。
在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:
- 非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java日期类最大的问题之一。
- 设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。
- 时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。
Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:
- Local(本地) − 简化了日期时间的处理,没有时区的问题,此外月份也从1开始计数
- ZoneId (时区) − 通过定制的时区处理日期时间。
本地化日期时间 API
LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日 历系统的日期、时间 、日期和时间。它们提供了简单的日期或时间,不包含与时区相关的信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49public class Demo2 { public static void main(String[] args) { //1.创建LocalDateTime,now不可变,和Calendar不同 System.out.println("--------获取并打印时间------------"); LocalDateTime now = LocalDateTime.now(); System.out.println(now.toLocalTime()); System.out.println(now.toLocalDate()); System.out.println(now); //2.创建昨天 System.out.println("--------创建昨天------------"); LocalDateTime yesterday = LocalDateTime.of(2019, 8, 16, 10, 10); System.out.println(yesterday); //3.创建明天 System.out.println("--------创建明天------------"); LocalDateTime localDateTime = now.plusDays(1); System.out.println(localDateTime); //4.获取时间字段 System.out.println("--------获取事件字段------------"); System.out.println("年" + now.getYear()); System.out.println("月" + now.getMonthValue()); System.out.println("月的天" + now.getDayOfMonth()); System.out.println("周的天" + now.getDayOfWeek()); System.out.println("小时" + now.getHour()); System.out.println("分钟" + now.getMinute()); System.out.println("秒" + now.getSecond()); } } //打印结果 --------获取并打印时间------------ 22:54:37.491 2019-08-18 2019-08-18T22:54:37.491 --------创建昨天------------ 2019-08-16T10:10 --------创建明天------------ 2019-08-19T22:54:37.491 --------获取事件字段------------ 年2019 月8 月的天18 周的天SUNDAY 小时22 分钟54 秒37
Instant、ZoneId
Instant 时间戳 类似以前的Date、Timestamp,它是以Unix元年(传统 的设定为UTC时区1970年1月1日午夜时分)开始 所经历的描述进行运算。
ZoneId 时区
获取方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31//创建Instant类对象 Instant instant = Instant.now(); //打印当前时间 System.out.println(instant.toString()); //获取毫秒数 System.out.println(instant.toEpochMilli()); //获取昨天 Instant instant1 = Instant.ofEpochMilli(System.currentTimeMillis() - (60 * 60 * 24 * 1000)); System.out.println(instant1.toString()); //计算时间差 System.out.println(Duration.between(instant1, instant).toHours()); //获取世界各地时区列表 Set<String> availableZoneIds = ZoneId.getAvailableZoneIds(); for (String availableZoneId : availableZoneIds) { System.out.println(availableZoneId); } //获取系统默认时区 ZoneId zoneId = ZoneId.systemDefault(); //从ID获取一个 ZoneId的实例,确保该ID有效并且可供使用;然后打印出此ID的时区规则,允许执行计算 ZoneId zone2 = ZoneId.of("Brazil/East"); System.out.println(zone2.getRules()); //打印结果: ZoneRules[currentStandardOffset=+08:00]
时间转换【重点】
利用毫秒数,Date转为Instant,再转为LocalDateTime
1
2
3
4
5
6
7
8//利用毫秒数,Date转为Instant,再转为LocalDateTime Date date = new Date(); Instant instant2 = date.toInstant(); //定位时区,然后获取localDate LocalDateTime localDateTime = instant2.atZone(ZoneId.systemDefault()).toLocalDateTime(); System.out.println(localDateTime);
LocalDateTime转Date
1
2
3
4Instant instant3 = localDateTime.atZone(ZoneId.systemDefault()).toInstant(); Date date1 = Date.from(instant3); System.out.println(date1.toLocaleString());
时间矫正器 TemporalAdjuster
TemporalAdjuster : 时间校正器。有时我们可能需要获取,例如:将日期调整到“下个周日”等操作。
TemporalAdjusters : 该类通过静态方法提供了大量的常 用 TemporalAdjuster 的实现。
1
2
3
4
5
6
7
8
9//date.with返回一个LocalDate类结果,打印年月日 LocalDate date=LocalDate.now(); //下一个周5 System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.FRIDAY))); //下一个周2 System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.TUESDAY))); //下一个周日(周日为每周的第一天) System.out.println(date.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
DateTimeFormatter日期格式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class Demo4 { public static void main(String[] args) { LocalDate date = LocalDate.now(); //时间格式化器 DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/M/d"); //按照格式将字符串解析 LocalDate parse = LocalDate.parse("2019/8/17", dtf); System.out.println(parse); //将现在时间按照固定格式转为字符串 String format = dtf.format(LocalDate.now()); System.out.println(format); } } //打印结果 2019-08-17 2019/8/18
LocalDateTime的web应用
web开发,涉及到后端的数据库和前端的页面,往往出现格式转化问题,尤其是时间问题,前端页面如果是Date属性,数据库也是Date则不会出现这个问题,java类的属性也可以使用Date。
现在,我们在前端可以在input标签中使用【datetime-local】,这个时间在后端通过request.getParameter() 方法获取后,是字符串,打印结果为【2019-09-12T14:37:20】,这个结果与java属性的【LocalDateTime】一致,而且完全可以放入数据库【对应数据库是DateTime】。
反过来,在前端展示也是可以的,但是前提是必须是【datetime-local】类型的标签。
如果不是,则需要在java类中新建一个时间的String属性,在业务层,将时间转为字符串,然后在前端直接通过【${}】展示即可。
最后
以上就是安详香烟最近收集整理的关于Java8新时间日期API的使用的全部内容,更多相关Java8新时间日期API内容请搜索靠谱客的其他文章。
发表评论 取消回复