JAVA8新特性--时间日期API

类库介绍

JAVA8中新增了java.time包,新的处理日期时间的类都放在此包下。
此处介绍几个比较重要的类及其API:

  • LocalDateTime:处理日期时间(年月日时分秒)的API。
  • LocalDate:处理日期(年月日)的API。
  • LocalTime:处理时间(时分秒)的API。
  • OffsetDateTime:一个使用UTC/Greenwich偏移量的满足ISO-8601日历系统的日期时间API。
  • ZonedDateTime:一个使用时区并且满足ISO-8601日历系统的日期时间API。
  • Instant:是个瞬时对象,是在一条时间线上建立一个时间点,可用于记录时间戳。
    LocalDateTime类会与LocalDate、LocalTime中有一些方法的交集,此处以LocalDateTime为主介绍下几个常用的API,以及LocalDate和LocalTime中的几个特别的方法。

LocalDateTimeLocalDateLocalTimeInstant比较容易区分,很明显就能看到区别。
OffsetDateTimeZonedDateTime则比较难以理解,在这重新说下这两个类的区别:

  • 相同点:这两个类库都包含日期和时间的所有字段,都精确到纳秒级,都能够显示时区的偏移。
  • 不同点
    • OffsetDateTime:只有一个时区的偏移对象(Offset),也就是说只能获取到时区的偏移量,获取不到其他的时区信息。
    • ZonedDateTime:类中能获取到偏移对象(Offset)时区对象(ZoneId),也就能够获取到时区的id等其他信息(下面会有例子演示)。

类库的API介绍

  • now():获取当前时间。
LocalDateTime dateTimeNow = LocalDateTime.now();
System.out.println("LocalDateTime=" + dateTimeNow.toString());

LocalDate dateNow = LocalDate.now();
System.out.println("LocalDate=" + dateNow.toString());

LocalTime timeNow = LocalTime.now();
System.out.println("LocalTime=" + timeNow.toString());

System.out.println("OffsetDateTime=" + OffsetDateTime.now());

System.out.println("ZonedDateTime=" + ZonedDateTime.now());

结果能很明显的看到几个类的区别,输出如下:

LocalDateTime=2018-04-17T19:53:54.500
LocalDate=2018-04-17
LocalTime=19:53:54.501
OffsetDateTime=2018-04-17T19:53:54.502+08:00
ZonedDateTime=2018-04-17T19:53:54.502+08:00[Asia/Shanghai]

  • of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond):API中有多个of方法,区别在于传递的参数个数不一样,此处介绍全部参数的例子:
//参数为:年、月、日、时、分、秒、纳秒
LocalDateTime dateTime = LocalDateTime.of(2015, 6, 12, 13, 14,15,504);

LocalDate date = LocalDate.of(2014, 2, 14);
//        LocalDate date = LocalDate.of(2012, Month.of(2), 29);

LocalTime time = LocalTime.of(13, 14, 15);
System.out.println("dateTime="+dateTime);
System.out.println("date="+date);
System.out.println("time="+time);

其中month参数也可以写成Month.of(2)或者调用常量:Month.FEBRUARY。其中nanoOfSecond是纳秒,1纳秒=十亿分之一秒。输出如下:

dateTime=2015-06-12T13:14:15.000000504
date=2014-02-14
time=13:14:15

  • isLeapYear:是否是闰年(LocalDate的方法) 。
System.out.println("leapYear = " + date.isLeapYear());

输出如下:

leapYear = false

  • withYear:复制一个日期将其中的年份替换为参数的中的值并返回复制的日期。如果替换后的日期在当前年中是不存在的,在返回当前月的最后一天。例:2012-02-29,年替换为2015后为返回2015-02-28(2012为闰年2月有29天,2015不是闰年2月只有28天)。
  • plusYears:复制一个日期将其中的年份加上为参数的中的值并返回复制的日期,日期不存在的处理同withYear一样。
  • minusYears:复制一个日期将其中的年份减去为参数的中的值并返回复制的日期,日期不存在的处理同withYear一样。
System.out.println("withYear="+date.withYear(2015));
System.out.println("plusYears="+date.plusYears(2015));
System.out.println("plusYears="+date.minusYears(2000));
//date值不变
System.out.println("date="+date);

所有以 “with“开头的方法都是替换参数里面的值;
所有以 “plus“开头的方法都是加上参数里面的值;
所有以 “minus“开头的方法都是减去参数里面的值;
使用 “with“、”plus“或者”minus“处理的方法,内部处理日期不存在的方式是不一样的,如”withDayOfMonth”和”withDayOfYear”处理是:如果参数中的日期不存在,则抛出异常。使用这些方法前可以看下方法的注释或者进入看下方法的源码就能知道内部是怎么处理的。
输出如下:

withYear=2015-02-14
plusYears=4029-02-14
plusYears=4014-02-14
date=2014-02-14

  • format(DateTimeFormatter formatter):日期转为字符串。DateTimeFormatter 为对应的格式化工具类。
    • DateTimeFormatter 提供常用的格式化方法,DateTimeFormatter.ofPattern(format),其中format常用的格式化用值:
      “yyyy-MM-dd HH:mm:ss.N”:年月日时分秒纳秒
      “yyyy-MM-dd HH:mm:ss.n”年月日时分秒纳秒
      N:从当前天0时0分0秒来计算的纳秒,范围: 0 ~ (24*60*60*1,000,000,000)-1
      n:对于当前秒来计算的纳秒,范围:1 ~ 1,000,000,000-1
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.N")));
System.out.println(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.n")));

因为N是从当前日期0时0分0秒来计算的,所以正常情况应该不会与”HH:mm:ss”同时使用,此处为演示代码才放在一块。输出为:

2018-04-17 19:31:03.70263915000000
2018-04-17 19:31:03.927000000

  • parse(CharSequence text, DateTimeFormatter formatter):字符串转日期。也可以为parse(CharSequence text),不使用formatter参数时,text参数格式必须为:”yyyy-MM-ddTHH:mm”,如:2018-04-17T19:42:46
String format = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

System.out.println(LocalDateTime.parse(format,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
System.out.println(LocalDateTime.parse(LocalDateTime.now().toString()));

输出为:

2018-04-17T19:45:59
2018-04-17T19:45:59.457

  • ofEpochSecond(long epochSecond, int nanoOfSecond, ZoneOffset offset):将秒转为日期,起始时间为:1970-01-01T00:00:00Z。接受三个参数:
    第一个参数:秒
    第二个参数:纳秒
    第三个参数:偏移对象
System.out.println(LocalDateTime.ofEpochSecond(1523951062,300, OffsetDateTime.now().getOffset()));

输出为:

2018-04-17T15:44:22.000000300

  • Instant.ofEpochSecond(long epochSecond):Instant类的方法,此类的方法创建出来的对象需要手动设置偏移量或者时区,否则获取的时间不是中国所在时区的时间。
System.out.println(Instant.ofEpochSecond(System.currentTimeMillis()/1000).atOffset(OffsetDateTime.now().getOffset()));
System.out.println(Instant.ofEpochSecond(System.currentTimeMillis()/1000).atZone(ZonedDateTime.now().getZone()));

输出为:

2018-04-17T20:03:55+08:00
2018-04-17T20:03:55+08:00[Asia/Shanghai]

偏移对象:可以通过ZonedDateTime类或者OffsetDateTime类获取,如下:

ZoneOffset offset = ZonedDateTime.now().getOffset();
ZoneOffset offset1 = OffsetDateTime.now().getOffset();

时区对象:只能通过ZonedDateTime类获取,如下:

ZoneId zone = ZonedDateTime.now().getZone();

总结:
处理日期时间格式,可以使用LocalDateTime类;
处理日期格式,可以使用LocalDate类;
处理时间格式,可以使用LocalTime类;
如果处理需要偏移量的日期时间格式,可以使用OffsetDateTime类或者ZonedDateTime类;
如果处理和时区相关的日期时间格式,可以使用ZonedDateTime类。

你可能感兴趣的:(JAVA)