大家好,我是指北君。
众所周知,Java 8 之前的 Date 相关的时间类非常的不好用。从 Java 8 之后开始加入了 LocalDate 等一系列更加现代化的时间类。
这就衍生出 Java 8 之前的 Date 需要和 LocalDate 互相转换的需求。今天指北君把这几年积累下来的转换代码分享给大家。
java.util.Date 与 java.time.LocalDate 之间的转换
在 Date 转换 LocalDate 的过程中,我们使用 Date 类中在 Java 8 新增的 toInstant() 方法进行转换。
当我们转换一个 Instant 对象时,需要使用 ZoneId,因为 Instant 对象是不分时区的–只是时间线上的点。
Instant 对象的 atZone(ZoneId zone) API 返回一个 ZonedDateTime,所以我们只需要使用 toLocalDate() 方法从中提取 LocalDate。
在这里我们使用的是系统默认的 ZoneId。
1 |
|
还有一个类似的解决方案,但用不同的方式来创建一个 Instant 对象–使用 ofEpochMilli() 方法。
1 |
|
在我们继续之前,让我们也快速看一下旧的 java.sql.Date 类,以及它是如何被转换为 LocalDate 的。
从 Java 8 开始,我们可以在 java.sql.Date 上找到一个额外的 toLocalDate() 方法,这也给了我们一个将其转换为 java.time.LocalDate 的简单方法。
在这种情况下,我们不需要担心时区的问题。
1 |
|
将 Date 转换为 LocalDateTime
为了得到一个 LocalDateTime 实例,我们同样可以使用一个中间的 ZonedDateTime,然后使用 toLocalDateTime() API。
就像以前一样,我们可以使用两种可能的解决方案来从java.util.Date中获得一个即时对象。
1 |
|
从Java 8开始,我们也可以使用java.sql.Timestamp来获得一个LocalDateTime。
1 |
|
将 LocalDate转换为 Date
现在我们已经很好地理解了如何从旧的数据表示法转换为新的数据表示法,让我们来看看另一个方向的转换。
我们将讨论将LocalDate转换为Date的两种可能方式。
第一种,我们使用java.sql.Date对象中提供的一个新的valueOf(LocalDate date)方法,它把LocalDate作为一个参数。
1 |
|
正如我们所看到的,它毫不费力,而且很直观。它使用本地时区进行转换(所有的工作都在引擎盖下完成,所以不用担心)。
在另一个Java 8的例子中,我们使用一个Instant对象,并将其传递给java.util.Date对象的from(Instant instant)方法。
1 |
|
注意我们在这里使用了一个即时对象,而且在做这个转换时我们还需要关心时区。
接下来,让我们使用一个非常类似的解决方案,将LocalDateTime转换为Date对象。
将java.time.LocalDateTime转换为java.util.Date
从 LocalDateTime 获得java.util.Date的最简单方法是使用java.sql.Timestamp的扩展–在Java 8中可用。
1 |
|
但当然,另一个解决方案是使用一个 Instant 对象,我们从ZonedDateTime中获得这个对象。
1 |
|
Java 9的新增功能
在 Java 9 中,有一些新方法可以简化java.util.Date和java.time.LocalDate或java.time.LocalDateTime之间的转换。
LocalDate.ofInstant(Instant instant, ZoneId zone) 和 LocalDateTime.ofInstant(Instant instant, ZoneId zone) 提供了方便的快捷方式。
1 |
|
总结
在这篇文章中,指北君介绍了将旧的java.util.Date转换为新的java.time.LocalDate和java.time.LocalDateTime的方式方法。