Nap*_*Nap 5 java java.util.date java-time
我在将旧日期从 java.time.LocalDateTime 转换为 java.util.Date 时遇到问题
我尝试了很多变化,但它仍然具有相同的转移日期。我认为这是执行了一些奇怪的日历,但它失败了。
要解析的日期1800-01-01 00:00:00
我使用了一个非常简单的转换函数。
Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
| 时区 | a.通过SimpleDateFormat转换 | b.通过DateFormatter将LocalDateTime转换为java.util.Date |
|---|---|---|
| 亚洲/东京 | 1800-01-01 00:00:00 日本标准时间 | 1799-12-31 23:41:01 日本标准时间 |
| 欧洲/布鲁塞尔 | 欧洲中部时间 1800-01-01 00:00:00 | 欧洲中部时间 1800 年 1 月 1 日 00:04:30 |
| 澳大利亚/悉尼 | 1800-01-01 00:00:00 澳大利亚东部时间 | 1799-12-31 23:55:08 澳大利亚东部时间 |
| 世界标准时间 | 1800-01-01 00:00:00 世界标准时间 | 1800-01-01 00:00:00 世界标准时间 |
A。通过 SimpleDateFormat 将 String 转换为 java.util.Date
b. 通过DateFormatter将String转换为java.time.LocalDatetime,然后将其转换为java.util.Date
现在我发现它只适用于 UTC 时区,我不能只更改软件时区,因为它会扰乱其他时区。有人知道将 java.time.LocalDateTime 转换为 java.util.Date 的其他方法吗?
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
=====以下是在扫地者的回答后添加的,以说明它并不适合所有人====
奇怪的是,它只发生在非常旧的日期,它不会发生在 1900-01-01 00:00:00,但尚未检查问题是在哪一点开始的。我在想,也许是因为18XX年的某个时候进行了调整/改变。
System.out.println(ZoneId.of("Asia/Tokyo").getRules().getOffset(LocalDateTime.parse("1800-01-01T00:00:00")));
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
System.out.println(TimeZone.getTimeZone("Asia/Tokyo").getOffset(format1.parse("1800-01-01T00:00:00").getTime()));
System.out.println(ZoneId.of("Asia/Tokyo").getRules().getOffset(LocalDateTime.parse("1900-01-01T00:00:00")));
SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
System.out.println(TimeZone.getTimeZone("Asia/Tokyo").getOffset(format2.parse("1900-01-01T00:00:00").getTime()));
Run Code Online (Sandbox Code Playgroud)
结果至
+09:18:59
32400000
+09:00
32400000
Run Code Online (Sandbox Code Playgroud)
与此问题类似,旧 API 不同意ZoneId.systemDefault()这些位置在 1800 年 1 月 1 日的偏移量。
您可以看到它的实际效果:
System.out.println(ZoneId.of("Asia/Tokyo").getRules().getOffset(LocalDateTime.parse("1800-01-01T00:00:00")));
var format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
System.out.println(TimeZone.getTimeZone("Asia/Tokyo").getOffset(format.parse("1800-01-01T00:00:00").getTime()));
Run Code Online (Sandbox Code Playgroud)
输出:
+09:18:59
32400000
Run Code Online (Sandbox Code Playgroud)
正如链接帖子中所述,+09:18:59 是日本当地时间,32400000ms 正好是 9 小时。这是因为旧的 API 不支持 Local Mean Time。请注意,日本于 1888 年标准化了时区,这解释了为什么两个 API 的输出在 1900-01-01 是一致的。
因此,ZoneId认为亚洲/东京的偏移量比(由等TimeZone使用的)所认为的多 18 分 59 秒。SimpleSateFormatDate.toString
这正是输出中存在“偏移”的原因。ldt.atZone(...)产生
1800-01-01T00:00:00+09:18:59
Run Code Online (Sandbox Code Playgroud)
并将toInstant其变成瞬间。
假设您正在使用Date.toString或其他一些用于TimeZone生成字符串的旧 API,旧 API 会认为该时刻是在 +09:00:00!上述日期 +09:00:00 是哪一天?好吧,只需减去 18 分 59 秒(就像减去 9 小时以将 UTC+9 日期转换为 UTC+0 一样)!
这就是你得到的:
1799-12-31 23:41:01
Run Code Online (Sandbox Code Playgroud)
至于解决方案,Date你得到的“转移”确实没有任何问题。如果您只是将其转换回 aZonedDateTime并将其格式化以DateTimeFormatter供显示,则一切都应该正常工作。事实上,如果可以的话,请考虑Date根本不转换为,而使用Instants 代替。
如果您做不到这一点,我建议您不要混合使用这两个 API。
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |