Java 函数式编程(五):Java 8 的日期和时间 API

1. Java 8 日期和时间 API 的优点?

答:

  • Java 8 以前的日期和时间 API,主要的类是 DateCalendar,由于它的设计有一些不足,Java 8 引入了一套新的 API,位于包 java.time
  • 它引入了更多的类,但概念更为清晰,更为强大和易用

2. Java 8 中表示日期和时间的类有?

答:

  • Instant:表示时刻,不直接对应年月日信息,需要通过时区转换。
  • LocalDateTime:表示与时区无关的日期和时间,不直接对应时刻,需要通过时区转换。
  • ZoneId/ZoneOffseet:表示时区
  • LocalDate:表示与时区无关的日期,与 LocalDateTime 相比,只有日期,没有时间信息。
  • LocalTime:表示与时区无关的时间,与 LocalDateTime 相比,只有时间,没有日期信息。
  • ZonedDateTime:表示特定时区的日期和时间

3. 怎样理解 Instant

答:

  • Instant 表示时刻,获取当前时刻:Instant now = Instant.now();
  • 可以根据 Epoch Time (纪元时)创建 Instant。比如,另一种获取当前时刻的代码为:Intant now = Instant.ofEpochMilli( Sytem.currentTimeMillis() );
  • Date 也表示时刻,IntantDate 可以通过纪元时相互转换
    • 转换 DateInstantpublic static Instant toInstant(Date date) { return Instant.ofEpochMilli(date.getTime()); }
    • 转换 IntantDatepublic static Date toDate(Instant instant) { return new Date(instant.toEpochMilli()); }

4. 怎样理解 LocalDateTime

答:

  • LocalDateTime 表示与时区无关的日期和时间,获取系统默认时区的当前日期和时间:LocalDateTime ldt = LocalDateTime.now();
  • 还可以直接用年月日等信息构建 LocalDateTime。比如,LocalDateTime ldt = LocalDateTime.of(2017, 7, 11, 20, 45, 5);
  • LocalDateTime 有很多方法,可以获取年月日时分秒星期等信息:
    • public int getYear()
    • public int getMonthValue()
    • public int getDayOfMonth()
    • public int getHour()
    • pubic int getMinute()
    • public int getSecond()
    • publict DayOfWeek getDayOfWeek()

5. 怎样理解 ZoneId/ZoneOffset

答:

  • LocalDateTime 不能直接转为时刻 Instant,转换需要一个参数 ZoneOffset
  • ZoneOffset 表示相对于格林尼治的时区差,北京是 +08:00。比如,转换一个 LocalDateTime 为北京的时刻:public static Instant boBeijingInstant(LocalDateTime ldt) { return ldt.toInstant(ZoneOffset.of("+08:00")); }
  • 给定一个时刻,使用不同时区解读,日历信息是不同的,Instant 有方法根据时区返回一个 ZonedDateTimepublic ZonedDateTime atZone(ZoneId zone)
  • 默认时区是 ZoneId.systemDefault(),可以这样构建 ZoneIdZoneId bjZone = ZoneId.of("GMT+08:00);
  • ZoneOffsetZoneId 的子类,可以根据时区差构造。

6. 怎样理解 LocalDate/LocalTime?

答:

  • 可以认为 LocalDateTime 由两部分组成,一部分是日期 LocalDate,另一部分是时间 LocalTime
  • LocalDate 加上时间可以构成 LocalDateTimeLocalTime 加上日期可以构成 LocalDateTime

7. 怎样理解 ZonedDateTime

答:

  • ZonedDateTime 表示特定时区的日期和时间,获取系统默认时区的当前日期和时间为:ZonedDateTime zdt = ZonedDateTime.now();
  • LocalDateTime.now() 也是获取默认时区的当前日期和时间,二者的区别是:LocalDateTime 内部不会记录时区信息,只会单纯记录年月日时分秒等信息,而 ZonedDateTime 除了记录日历信息,还会记录时区,它的其他大部分构建方法都需要显示传递时区。
  • ZonedDateTime 可以直接转换为 InstantZonedDateTime ldt = ZonedDateTime.now(); Instant now = ldt.toInstant();

8. Java 8 中的格式化?

答:Java 8 中,主要的格式化类是 java.time.format.DateTimeFormatter,它是线程安全的

  • 举例:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    LocalDateTime ldt = LocalDateTime.of(2016, 8, 18, 14, 20, 45);
    System.out.println(formatter.format(ldt));
    
    输出为:2016-08-18 14:20:45
    
    // 将字符串转化为日期和时间对象,可以使用对应类的 parse 方法
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String str = "2016-08-18 14:20:45";
    LocalDateTime ldt = LocalDateTime.parse(str, formatter);
    

9. Java 8 中怎样设置/修改时间?

答:

  • 修改时期和时间有两种方式,一种是直接设置绝对值,另一中是在现有值的基础上进行相对增减操作Java 8 的大部分类都支持这两种方法。
  • Java 8 的大部分类都是不可变类,修改操作是通过创建并返回新对象来实现的,原对象本身不会变

10. Java 8 中时间段的计算?

答:

  • Java 8 中表示时间段的类主要有两个:PeriodDuration
  • Period 表示日期之间的差,用年月日表示,不能表示时间
  • Duration 表示时间差,用时分秒表示,也可以用天表示,一天严格等于 24 小时,不能用年月表示

11. Java 8 中与 Date/Calendar 对象的转换?

答:

  • Java 8 的日期和时间 API 没有提供与老的 Date/Calendar 相互转换的方法,但在实际中,我们可能是需要的。
  • Date 可以与 Instant 通过毫秒数相互转换,对于其他类型,也可以通过毫秒数/ Instant 相互转换
-------------本文结束感谢您的阅读-------------