> 文档中心 > 记录一次时间戳、夏令时、时区线上问题分析

记录一次时间戳、夏令时、时区线上问题分析


问题描述

问题:输入时间戳、时区,返回一个带时区的时间字符串?

代码如下:

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。