记录一次时间戳、夏令时、时区线上问题分析
问题描述
代码如下:
long timestamp = 1647489600000L; // 2022-03-15 12:00:00 Asia/ShanghaiString timeZoneName = "America/New_York";Instant instant = Instant.ofEpochMilli(timestamp);ZonedDateTime zonedDateTime = ZonedDateTime.of(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()),TimeZone.getTimeZone(timeZoneName).toZoneId());System.out.println(zonedDateTime);ZonedDateTime zonedDateTime1 = ZonedDateTime.of(LocalDateTime.ofInstant(instant, ZoneId.systemDefault()),TimeZone.getTimeZone("Asia/Shanghai").toZoneId());System.out.println(zonedDateTime1);复制代码
输出结果如下:
几个类简单说明一下:
-
Instant
可以将时间戳转换为本地日期/时间LocalDateTime
。 -
在
JDK 8
之前,Java使用java.util.TimeZone
来表示时区。而在JDK 8里分别使用了ZoneId
表示时区,ZoneOffset
表示UTC
的偏移量。 -
ZonedDateTime
是一个带时区的日期类。
夏令时(DST)
我们知道,纽约是 西五区
,上海是 东八区
那么应该和我们的时间相差13 个小时(因为一个时区就是相差一个小时),但是我们得到的结论,确实是相差了 12 个小时,是不是有点怀疑自己。
再来看看,居然是 11 点,明明是相差 12 个小时,为什么说是比北京时间慢 14 小时这就是由于当前时间是夏令时导致的。【编程学习资料点击免费领取】
一个特殊的例子:
ZonedDateTime zonedDateTime2 = ZonedDateTime.ofInstant(instant,TimeZone.getTimeZone("GMT-05:00").toZoneId());System.out.println(zonedDateTime2);// 结果:2022-03-16T23:00-05:00[GMT-05:00]复制代码
如果我们使用 GMT-05:00
来获取时区的时间,那么就不会触发夏令时,可能会和你想象的结果不同。
换句话说 America/New_York
可能是 GMT-05:00
也可能是 GMT-04:00
这个具体要看 LocalDateTime
是否在夏令时的时间区间内.
总结一下
1、如果按照用户侧,百度上的时间来算,由于现在是夏令时,所以 America/New_York
方式的时区才能正确的获取本地时间。
2、 具体的 Java 几个日期类的差别,大家可以看看参考资料中的文件。
3、 对于时区,时间戳,夏令时来说,相互转换有时候特别容易混淆。
①3000多本Python电子书有
②Python开发环境安装教程有
③Python400集自学视频有
④软件开发常用词汇有
⑤Python学习路线图有
⑥项目源码案例分享有如果你用得到的话可以直接拿走,在我的QQ技术交流群里(技术交流和资源共享,广告勿入)可以自助拿走,群号是895937462。