Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。对日期与时间的操作一直是Java程序员最痛苦的地方之一。标准的 java.util.Date以及后来的java.util.Calendar一点没有改善这种情况(可以这么说,它们一定程度上更加复杂)。
这种情况直接导致了Joda-Time——一个可替换标准日期/时间处理且功能非常强大的Java API的诞生。Java 8新的Date-Time API (JSR 310)在很大程度上受到Joda-Time的影响,并且吸取了其精髓。新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。在设计新版API时,十分注重与旧版API的兼容性:不允许有任何的改变(从java.util.Calendar中得到的深刻教训)。如果需要修改,会返回这个类的一个新实例。
让我们用例子来看一下新版API主要类的使用方法。第一个是Clock类,它通过指定一个时区,然后就可以获取到当前的时刻,日期与时间。Clock可以替换System.currentTimeMillis()与TimeZone.getDefault()。
1
2
3
4
|
// Get the system clock as UTC offset
final
Clock clock = Clock.systemUTC();
System.out.println( clock.instant() );
System.out.println( clock.millis() );
|
下面是程序在控制台上的输出:
1
2
|
2014-04-12T15:19:29.282Z
1397315969360
|
我们需要关注的其他类是LocaleDate与LocalTime。LocaleDate只持有ISO-8601格式且无时区信息的日期部分。相应的,LocaleTime只持有ISO-8601格式且无时区信息的时间部分。LocaleDate与LocalTime都可以从Clock中得到。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// 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 );
|
下面是程序在控制台上的输出:
1
2
3
4
|
2014-04-12
2014-04-12
11:25:54.568
15:25:54.568
|
LocaleDateTime把LocaleDate与LocaleTime的功能合并起来,它持有的是ISO-8601格式无时区信息的日期与时间。下面是一个快速入门的例子。
1
2
3
4
5
6
|
// Get the local date/time
final
LocalDateTime datetime = LocalDateTime.now();
final
LocalDateTime datetimeFromClock = LocalDateTime.now( clock );
System.out.println( datetime );
System.out.println( datetimeFromClock );
|
下面是程序在控制台上的输出:
1
2
|
2014-04-12T11:37:52.309
2014-04-12T15:37:52.309
|
如果你需要特定时区的日期/时间,那么ZonedDateTime是你的选择。它持有ISO-8601格式具具有时区信息的日期与时间。下面是一些不同时区的例子:
1
2
3
4
5
6
7
8
|
//
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 );
|
下面是程序在控制台上的输出:
1
2
3
|
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使计算两个日期间的不同变的十分简单。下面让我们看一个这方面的例子。
1
2
3
4
5
6
7
|
// 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年4月16号之间的过程。下面是程序在控制台上的输出:
1
2
|
Duration
in
days: 365
Duration
in
hours: 8783
|
对Java 8在日期/时间API的改进整体印象是非常非常好的。一部分原因是因为它建立在“久战杀场”的Joda-Time基础上,另一方面是因为用来大量的时间来设计它,并且这次程序员的声音得到了认可。