你好呀,我是歪歪。
给大家分享一个我最近发现的有点意思,但是卵用不大的小知识点。
先给你搞个程序看一下:
public class MainTest { public static void main(String[] args) throws Exception { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = simpleDateFormat.parse("1900-01-01 08:00:00"); System.out.println(simpleDateFormat.format(date)); } }
你说上面的程序逻辑就是一个简单的时间格式化,你说输出结果是什么?
只是需要瞟一眼就知道,肯定是输出这个结果呀:
1900-01-01 08:00:00
但是,你把上面的程序拿出来,直接跑起来,你会发现输出结果竟然是这样的:
1900-01-01 08:05:43
当时就懵逼了。
我知道时差 8 小时,是因为有时区问题。
我知道时间差 1 小时,是因为有夏令时的原因。
但是这里差了 5 分 43 秒,有零有整,就让我有点摸不着头脑了。
上面这个案例就是一个读者分享给我的,他们在数据库里面默认时间是 1900-01-01,再加上时区问题,刚好变成了 1900-01-01 08:00:00,于是在通过程序做数据迁移的时候就踩到了这个莫名其妙的时间问题。
同时他还给我附送了一个关于这个 bug 的链接:
我乍一看,这个 bug 还挺新的呢,属于今年提出来的。
仔细又看了一眼发现是和之前的 bug 重复了:
但是这里提到了原因:
他说可以看一下这个链接https://www.timeanddate.com/time/zone/china/shanghai?year=1900
这里面,在 1900 年的时候,发生了一个变化:
The timezone offset was UTC +8:05:43 hours all of the period.
虽然我没太看明白具体是什么意思,但是我看到了“5 分 43 秒”:
我理解就是由于时区的变化,导致时间发生了重置。
接着我顺藤摸瓜,在 stackoverflow 上找到了这个:
当时我就震惊了。
这个 10 年前被提出的问题居然已经被浏览过 746k 次了,非常热门的问题了,我居然没注意到过:
这个问题具体是这样的:
你就大概瞟一眼,我给你翻译翻译。
提问者说,他发现 1927-12-31 23:54:07 到 1927-12-31 23:54:08 之间差了 353 秒,按理来说应该是 1 秒才对啊?
但是把时间改成下面这样,又正常了:
String str3 = "1927-12-31 23:54:07"; String str4 = "1927-12-31 23:54:08";
我把程序粘出来你也可以跑一下,看看结果非常的神奇啊:
public static void main(String[] args) throws ParseException { SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String str3 = "1927-12-31 23:54:07"; String str4 = "1927-12-31 23:54:08"; Date sDt3 = sf.parse(str3); Date sDt4 = sf.parse(str4); long ld3 = sDt3.getTime() /1000; long ld4 = sDt4.getTime() /1000; System.out.println(ld4-ld3); }
但是当我跑了一遍之后,我发现:我去,说好的 353 秒呢?
跑出来怎么是 1 秒呢,毫无毛病啊:
我甚至怀疑是 jdk 版本的问题,于是我换了 jdk 9,11,15 都跑了一下,都是 1 秒。
这就很奇怪了啊。
感觉这个问题提的就有问题啊。