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

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

问题描述


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


代码如下:


long timestamp = 1647489600000L; // 2022-03-15 12:00:00  Asia/Shanghai
String 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);


输出结果如下:


image.png


几个类简单说明一下:


  • Instant 可以将时间戳转换为本地日期/时间 LocalDateTime


  • JDK 8 之前,Java使用 java.util.TimeZone 来表示时区。而在JDK 8里分别使用了 ZoneId 表示时区,ZoneOffset 表示 UTC 的偏移量。


  • ZonedDateTime 是一个带时区的日期类。


夏令时(DST)


我们知道,纽约是 西五区,上海是 东八区  那么应该和我们的时间相差13 个小时(因为一个时区就是相差一个小时),但是我们得到的结论,确实是相差了 12 个小时,是不是有点怀疑自己。


image.png


再来看看,居然是 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 是否在夏令时的时间区间内.


如何通过 America/New_York 获取到 GMT-xx


一个简单的方法


ZonedDateTime of = ZonedDateTime.of(LocalDateTime.now(ZoneId.of("America/New_York")), ZoneId.of("America/New_York"));
System.out.println(of.getOffset().getId());


输出:


-04:00


思路来源于


image.png


说明一下:


ZonedDateTime 包括 LocalDateTimeZoneId 我们将 -04:00 加上 GTM 前缀就可以了,而且已经包含夏令时的处理。


总结一下


1、如果按照用户侧,百度上的时间来算,由于现在是夏令时,所以 America/New_York 方式的时区才能正确的获取本地时间。


2、 具体的 Java 几个日期类的差别,大家可以看看参考资料中的文件。


3、 对于时区,时间戳,夏令时来说,相互转换有时候特别容易混淆。


参考资料




相关文章
|
消息中间件 SQL API
Flink线上问题汇总篇(2)-时区不一致系统时间少8小时导致数据丢失问题
flink按月度汇总数据,月初时数据部分丢失问题
1584 0
|
2月前
|
SQL 存储 关系型数据库
真正线上索引失效的问题是如何排查的
MySQL索引失效是一种常见问题,在处理慢查询时经常需要考虑索引失效的可能性。 针对索引失效的排查,关键步骤包括确定需要分析的SQL语句,并通过`EXPLAIN`查看其执行计划。主要关注`type`、`key`和`extra`这几个字段。
真正线上索引失效的问题是如何排查的
|
8月前
|
安全 关系型数据库 MySQL
记一次MS14-058到域控实战记录
记一次MS14-058到域控实战记录
105 0
记一次MS14-058到域控实战记录
|
10月前
|
SQL 关系型数据库 MySQL
mysql线上连接超时和字段过长排查思路
mysql线上连接超时和字段过长排查思路
在线时间戳转换工具的坑-同样的时间戳转为北京时间,转换结果受本机时区设置的影响...
在线时间戳转换工具的坑-同样的时间戳转为北京时间,转换结果受本机时区设置的影响...
196 0
【SQL开发实战技巧】系列(十七):数据仓库中时间类型操作(初级)确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数
如何确定两个日期之间的工作日有多少天、计算—年中每周内各日期出现次数、确定当前记录和下一条记录之间相差的天数【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。本章节的三个需求:确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数有些许难度,不过建议还是学会比较好。
【SQL开发实战技巧】系列(十七):数据仓库中时间类型操作(初级)确定两个日期之间的工作天数、计算—年中周内各日期出现次数、确定当前记录和下一条记录之间相差的天数
|
XML 安全 调度
时间戳:互联网上的日期和时间
日期和时间格式在 Internet 上引起了很多混乱和互操作性问题。本文档解决了在 Internet 协议中表示和使用日期和时间时遇到的许多问题,并提出了改进一致性和互操作性的建议。
662 0
时间戳:互联网上的日期和时间
|
数据库
mybaits传入的时间参数与数据库实际插入的时间晚8个小时
mybaits传入的时间参数与数据库实际插入的时间晚8个小时
90 0
mybaits传入的时间参数与数据库实际插入的时间晚8个小时
|
SQL
根据时间字段删除一定时间内的记录
根据时间字段删除一定时间内的记录
96 0
|
存储 JSON 缓存
Laravel 7.0中 timestamp 取出来的时间慢的8小时问题
部署博客后,评论的时间不正确,比正常时间慢了8小时; 都是用的 timestamp 字段存储的时间,只有评论留言取出来的时间慢的8小时,其他没有页面没有;
235 0