-
-
java8 datetime api有什么
-
LocalDate
-
LocalDate 与 Date 转换
-
LocalTime
-
LocalDateTime
-
LocalDateTime 与 Date
-
Instant
-
ZoneId
-
日期计算
Java的日期时间API,一直有一些令人头疼的问题。
有了 java.util.Date 又搞出个java.sql.Date,改个名字不行?
好好的new Date(year,month,day) 早早的就被标记为 @Deprecated,那时候还是jdk1.1,如今都java9了,还没删除。
好吧,又给了一个Calendar,每次一个操作,都感觉,IDE一行设置80个字符,是真不够。
我想搞个纯日期,那叫一个麻烦,相信很多人都这么写:
Calendar cal=Calendar.getInstance(); cal.set(Calendar.HOUR,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); Date date=cal.getTime();
心塞~
貌似看起来Calendar比Date好一点,但他继承了Date一个很恶心的特性,月份问题。
System.out.println(cal.getTime()); System.out.println(cal.get(Calendar.MONTH));
java8终于有了个改观,那就是引入了joda-time的API,虽然仍然没有joda好用。
java8 datetime api有什么?
日期时间API将日期和时间分开为LocalDate和LocalTime;
既有日期又有时间,则使用 LocalDateTime;
改善了jdk的TimeZone,使用更优雅的ZoneId;
增加了 Instant 的概念,可以理解为时间线上的一个瞬间;
LocalDate
LocalDate date1=LocalDate.now(); System.out.println(date1); LocalDate date2=LocalDate.of(2017, 12, 24); System.out.println(date2); LocalDate minus = date1.minus(date1.getDayOfMonth()-1,ChronoUnit.DAYS); System.out.println(minus);
LocalDate 与 Date 转换
LocalDate localDate1=LocalDate.now(); ZoneId zoneId=ZoneId.systemDefault(); Instant instant=localDate1.atStartOfDay(zoneId).toInstant(); Date from = Date.from(instant); System.out.println(from); Date date2=new Date(); Instant instant = date2.toInstant(); ZoneId zoneId=ZoneId.systemDefault(); LocalDate localDate2 = instant.atZone(zoneId).toLocalDate(); System.out.println(localDate);
LocalTime
实际单纯使用时间的场景,并没有单纯使用日期的时间多。而且,LocalDate的思路捋清楚,LocalTime的使用大同小异,以后再补充吧。
LocalDateTime
结合了LocalDate 和 LocalTime,也就是传统意义上类似Date的时间。
LocalDate localDate = dt.toLocalDate(); LocalTime localTime = dt.toLocalTime();
LocalDateTime 与 Date
Date 转 LocalDateTime
Date date = new Date(); Instant instant = date.toInstant(); ZoneId zone = ZoneId.systemDefault(); LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); # LocalDateTime 转 Date
LocalDateTime localDateTime = LocalDateTime.now(); ZoneId zone = ZoneId.systemDefault(); Instant instant = localDateTime.atZone(zone).toInstant(); Date date = Date.from(instant);
Instant
从前面的格式转换可以看出。
Date -> Instant -(ZoneId)-> LocalDate
用文字描述,就是 Date 可以转换为 Instant;Instant 可以借助ZoneId 转换为LocalDate。反之亦然。
ZoneId
ZoneId zoneId=ZoneId.systemDefault(); System.out.println(zoneId); TimeZone tz=TimeZone.getDefault(); System.out.println(tz);
输出:
Asia/Shanghai
sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
ZoneId忽略了哪些用处不大的信息,更清晰。如果必要的时候,可以在属性 zoneId.getRules()
中获取。
日期计算
在日期计算上,引入的joda-time特性,实在太方便了。
比如,如果要得到本月的天的日期,那么以前我们需要这么做。
Calendar cal=Calendar.getInstance(); cal.set(Calendar.HOUR,0); cal.set(Calendar.MINUTE,0); cal.set(Calendar.SECOND,0); cal.set(Calendar.DAY_OF_MONTH,1); System.out.println(cal.getTime());
现在呢?
LocalDate date=LocalDate.now().withDayOfMonth(1); System.out.println(date);
如果我们希望计算当前时间的前一天的时刻,以前需要这么做:
Calendar cal=Calendar.getInstance(); cal.add(Calendar.DAY_OF_MONTH, -1);
现在呢?
LocalDateTime date=LocalDateTime.now().minusDays(1);
既简单,语义也更佳。支持链式语法,编码方便。