日期时间API(JSR310)
Java 8引入了新的日期时间API(JSR 310)改进了日期时间的管理。日期和时间管理一直是Java开发人员最痛苦的问题。java.util.Date和后来的java.util.Calendar一点也没有改变这个情况(甚至让人们更加迷茫)。
因为上面这些原因,产生了Joda-Time ,可以替换Java的日期时间API。Joda-Time深刻影响了 Java 8新的日期时间API,Java 8吸收了Joda-Time 的精华。新的java.time包包含了所有关于日期、时间、日期时间、时区、Instant(跟日期类似但精确到纳秒)、duration(持续时间)和时钟操作的类。设计这些API的时候很认真地考虑了这些类的不变性(从java.util.Calendar吸取的痛苦教训)。如果需要修改时间对象,会返回一个新的实例。
让我们看看一些关键的类和用法示例。第一个类是Clock,Clock使用时区来访问当前的instant, date和time。Clock类可以替换 System.currentTimeMillis() 和 TimeZone.getDefault().
// Get the system clock as UTC offset
final Clock clock = Clock.systemUTC();
System.out.println( clock.instant() );
System.out.println( clock.millis() );
控制台输出如下:
2014-04-12T15:19:29.282Z
1397315969360
其他类我们看看LocalTime和LocalDate。LocalDate只保存有ISO-8601日期系统的日期部分,有时区信息,相应地,LocalTime只保存ISO-8601日期系统的时间部分,没有时区信息。LocalDate和LocalTime都可以从Clock对象创建。
// Get the local date and local time
final LocalDate date = LocalDate.now();
final LocalDate dateFromClock = LocalDate.now( clock );
System.out.println( date );
System.out.println( dateFromClock );
// Get the local date and local time
final LocalTime time = LocalTime.now();
final LocalTime timeFromClock = LocalTime.now( clock );
System.out.println( time );
System.out.println( timeFromClock );
控制台输出如下:
2014-04-12
2014-04-12
11:25:54.568
15:25:54.568
LocalDateTime类合并了LocalDate和LocalTime,它保存有ISO-8601日期系统的日期和时间,但是没有时区信息。让我们看一个简单的例子。
// Get the local date/time
final LocalDateTime datetime = LocalDateTime.now();
final LocalDateTime datetimeFromClock = LocalDateTime.now( clock );
System.out.println( datetime );
System.out.println( datetimeFromClock );
输出如下:
2014-04-12T11:37:52.309
2014-04-12T15:37:52.309
如果您需要一个类持有日期时间和时区信息,可以使用ZonedDateTime,它保存有ISO-8601日期系统的日期和时间,而且有时区信息。让我们看一些例子:
// Get the zoned date/time
final ZonedDateTime zonedDatetime = ZonedDateTime.now();
final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now( clock );
final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) );
System.out.println( zonedDatetime );
System.out.println( zonedDatetimeFromClock );
System.out.println( zonedDatetimeFromZone );
输出如下:
2014-04-12T11:47:01.017-04:00[America/New_York]
2014-04-12T15:47:01.017Z
2014-04-12T08:47:01.017-07:00[America/Los_Angeles]
最后让我们看看Duration类,Duration持有的时间精确到纳秒。它让我们很容易计算两个日期中间的差异。让我们来看一下:
// Get duration between two dates
final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 );
final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 );
final Duration duration = Duration.between( from, to );
System.out.println( "Duration in days: " + duration.toDays() );
System.out.println( "Duration in hours: " + duration.toHours() );
上面的例子计算了两个日期(2014年4月16日和2014年5月16日)之间的持续时间(基于天数和小时)输出如下:
Duration in days: 365
Duration in hours: 8783
对于Java 8的新日期时间的总体印象还是比较积极的。一部分是因为有经历实战的Joda-Time的基础,还有一部分是因为日期时间终于被认真对待而且听取了开发人员的声音。关于更多的详细信息,请参考官方文档。