【发布时间】:2020-04-02 08:23:38
【问题描述】:
从 Android Studio 4 开始,出色的 java.time API 可用于 Android。
在我的项目中,我想从 java.util.Date 逐步迁移到新的 API。
如何在这两种格式之间进行转换?
【问题讨论】:
标签: android java.util.date java-time android-studio-4.0
从 Android Studio 4 开始,出色的 java.time API 可用于 Android。
在我的项目中,我想从 java.util.Date 逐步迁移到新的 API。
如何在这两种格式之间进行转换?
【问题讨论】:
标签: android java.util.date java-time android-studio-4.0
首先,我想指出严重的差异。
java.time API 在明确不同的时间概念方面做得很好,例如如果您想代表某个时间点或Duration。
在第一种情况下,您可以选择是否要表示日期、时间或两者兼而有之,以及是否希望它能够感知时区,例如
LocalDate(日期、时间、时区)LocalDateTime(日期、时间、无时区)ZonedDateTime(日期、时间、时区)Instant 表示时间戳(自 UTC 时间 01.01.1970 以来的纳秒)。所以它是时间的机器表示,也是其他类的构建块。
要查看所有课程,请参阅java.time API documentation。
Date 的方法建议它代表一个日期和时间。在内部,它只存储一个时间戳(自 01.01.1970 UTC 以来的毫秒数)并且没有时区。
推荐的创建方法是使用时区感知Calendar 类。但是,Date 本身是通过隐式使用计算机运行所在的时区生成的。
调用toString() 格式化输出可能会显示时区,但它是从Calendar 实例外部获取的,这导致混淆Date 会存储时区。
总而言之,API 设计不佳,可能会造成混淆。 java.time 更优越,如果可用,应该使用。
那么这两个 API 是如何连接的呢? -> 通过Instant.
在 java 8 中,java.util.Date 使用两种方法进行了扩展:
public static Date from(Instant instant)public Instant toInstant()这是两个 API 之间的内置桥梁!
我们可以在此基础上构建更多的适配器功能。
这是一个示例(在 Kotlin 中),其中包含 LocalDate 和 LocalDateTime 类的转换:
/**
* java.util.Date has no explicit time zone but implicitly uses the system's time zone
*/
private val dateZoneId: ZoneId = ZoneId.systemDefault()
fun Date.toLocalDate(): LocalDate = toInstant().atZone(dateZoneId).toLocalDate()
fun LocalDate.toDate(): Date = Date.from(atStartOfDay(dateZoneId).toInstant())
fun Date.toLocalDateTime(): LocalDateTime = toInstant().atZone(dateZoneId).toLocalDateTime()
fun LocalDateTime.toDate(): Date = Date.from(atZone(dateZoneId).toInstant())
【讨论】:
java.util.Date 直接对应于自 Unix 纪元以来以毫秒为单位测量的瞬间。好吧,它的方法toString() 在默认时区将瞬间打印为日期和时间,这会引起很多混乱。
Date 的内部状态是一个时间戳。