我想将
java.util.Date
解析为 java.time.LocalDate
当我搜索问题时,我发现了这段代码:
date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
如果我将
01.01.0001
作为开始日期,我会遇到问题:
date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
==> (java.time.LocalDate) 0000-12-29
29.12.0000
和 01.01.0001
不一样。
LocalDate
的01.01.0001
,我该怎么办?了解 Java 附带两种不同的日期时间框架。其中一个有严重缺陷,现在已成为遗产。另一个是行业领先的,在 JSR 310 中定义,所有类都可以在
java.time.*
包中找到。
让我们迎来新的一年的第一个时刻 1.
Instant yearOneStartInUtc = Instant.parse ( "0001-01-01T00:00:00Z" );
yearOneStartInUtc.toString() = 0001-01-01T00:00:00Z
末尾的
Z
发音为“Zulu”,表示与 UTC 时间子午线的零时-分-秒偏移。
我们可以通过调用添加到旧类中的新方法来在遗留框架和现代框架之间自由地来回转换。
java.util.Date judStart = java.util.Date.from ( yearOneStartInUtc );
judStart.toString() = 太平洋标准时间 1 月 2 日星期日 16:00:00 1
请注意,
java.util.Date#toString
方法对我们撒了谎。虽然 java.util.Date
表示 UTC 中的时刻(偏移量为零),但其 toString
方法在生成文本结果时动态应用 JVM 当前的默认时区。这是避免这个遗留类以及Calendar
、SimpleDateFormat
等的众多原因之一。
现在我们可以查看其余的代码。
您将时区应用于
Instant
以根据 UTC 进行调整。您忘记告诉我们那个时区是什么。所以我们任意选择时区America/Edmonton
。该时区比 UTC 晚几个小时。
ZoneId zoneEdmonton = ZoneId.of ( "America/Edmonton" );
ZonedDateTime zdtYearOneStart = yearOneStartInUtc.atZone ( zoneEdmonton );
zdtYearOneStart.toString() = 0000-12-31T16:26:08-07:33:52[美国/埃德蒙顿]
请注意日期与输入不同,0000-12-31 与 0001-01-01。时间也不同,16:26:08-07:33:52 与 00:00:00。这就是我们的解释。就在这一天、一年翻过来的那一刻,当爱丽丝站在未来的格林威治皇家天文台所在地时,时间是元旦的 00:00:00。但对于在卡尔加里小酌一杯的鲍勃来说,同一时刻是除夕夜,而不是新年日。当鲍勃抬头看墙上的时钟时,他会看到午夜前几个小时的时间。 Alice 处于“明年”0001,而 Bob 同时处于“去年”0000。 👉🏽 对于任何特定时刻,全球各地的时间和日期会因时区而异。