当前位置: 首页 > 后端技术 > Java

这个问题有746,000次浏览,让我大吃一惊!

时间:2023-04-01 21:18:16 Java

大家好,我是伟伟。给大家分享一个最近发现的比较有意思,但是用处不大的小知识点。让我先给你看一个程序:日期date=simpleDateFormat.parse("1900-01-0108:00:00");System.out.println(simpleDateFormat.format(date));}}你说上面的程序逻辑是一个简单的时间格式,你说输出结果是什么?看一眼就知道输出的一定是这个结果:1900-01-0108:00:00但是如果把上面的程序拿出来直接运行,你会发现输出的结果是这样的this:1900-01-0108:05:43我当时就懵了。我知道8小时的差异是由于时区问题。因为夏令时,我知道时差是1小时。但是这里相差了5分43秒,让我有点摸不着头脑。以上案例是一位读者分享给我的。他们在数据库中的默认时间是1900-01-01。再加上时区问题,刚好变成了1900-01-0108:00:00。在数据迁移的过程中,踩到了这个莫名其妙的时间问题。同时,他还给我发了一个关于这个bug的链接:https://bugs.openjdk.java.net...乍一看,这个bug挺新的,今年才提出来的。仔细一看,发现和之前的bug重复了:不过这里说了原因:他说可以看看这个链接https://www.timeanddate.com/time/zone/china/shanghai?year=1900,在1900年,发生了一个变化:整个时期的时区偏移量都是UTC+8:05:43小时。虽然不太明白是什么意思,但是看到“5分43秒”:我明白是因为时区的变化,时间重新设置了。然后顺着线索在stackoverflow上找到了这个:https://stackoverflow.com/que...惊呆了。这个问题在10年前提出,目前已被浏览746k次。很火的一道题,我没注意过:这道题具体是这样的:你随便看一眼,我给你翻译。提问者说他??发现1927-12-3123:54:07和1927-12-3123:54:08相差了353秒。按道理应该是1秒吧?但是把时间改成如下,又正常了:Stringstr3="1927-12-3123:54:07";Stringstr4="1927-12-3123:54:08";我会把程序贴出来给你你也可以运行它看看惊人的结果:);Stringstr3="1927-12-3123:54:07";Stringstr4="1927-12-3123:54:08";日期sDt3=sf.parse(str3);日期sDt4=sf.parse(str4);长ld3=sDt3.getTime()/1000;长ld4=sDt4.getTime()/1000;System.out.println(ld4-ld3);}但是我运行的时候发现:我去,sayok353秒呢?为什么它运行了1秒?没毛病:我什至怀疑是jdk版本的问题,于是换了jdk9、11、15再跑,都是1秒。这很奇怪。感觉这个问题有点问题。但是在我看了下面点赞最多的回答后,我好像又是一瞥。这个答案比较长,我把它全部截图给大家看看:之所以长,是因为作者修改了几次答案。为什么我要改变我的答案?让我们回过头来看,所有的答案都藏在其中。我会为你选择关键的。先看第一段:他说12月31日(1927年),上海的时区改变了。至于1927年上海的详细情况,他附上了一个超链接,就是之前出现的那个网站。点开之后是这样的:但是显示:1927年上海没有进一步的时间变化。译文是:上海1927年的时间没有再变化,这不符合他下面说的吗?他接着说,在1927年底的午夜,时钟拨慢了5分52秒。所以“1927-12-3123:54:08”实际上发生了两次,而Java抓住了第二次的时刻,所以是有区别的。当我看到这个的时候,我真的惊呆了。这个东西不匹配,所以我开始寻找。直到我发现这个:https://coolshell.cn/articles...这也是十年前的文章了。在这里,笔者截取了当时的网站截图:当年的截图显示:1927年12月31日23:59:59,下一秒应该是1928年1月1日0:0:0,但是这次时间往回调了5分52秒,变成了1927年12月31日的23:54:08,这样352秒的穿越就完成了。这说明什么?说明数据被篡改了,网页上的信息被人篡改了!究竟发生了什么?我们回到stackoverflow往下看:这是他第一次修改他的答案,因为Historychanges...historyhaschanged...他这里说如果用TZDB2013a版本的数据,原来的问题将不正确。再次表现出完全相同的行为。在2013a中,结果将是358秒,过渡时间为23:54:03而不是23:54:08。他提到了一个TZDB,它是什么?我也不知道,但我用谷歌搜索。他应该说的是这样的话。https://www.iana.org/time-zones名字你就知道了,它是一个时区数据库,里面应该包含维护的时区相关的数据。也就是说,在这个时区数据库中,使用2013a版本的数据,之前的代码是另一种输出。也就是说,数据确实发生了变化。关键答案在于下一个编辑:历史再次改变......历史再次改变。时区数据库,在2014f版本中,变更的时间被移到了1900-12-31,现在只变更了343秒。343秒?那不是比我们早5分43秒吗?好吧,现在时差是对的,343秒,但是时间还是不对。我们的测试时间是1900-01-0108:00:00,他这里写的时间是1900-12-31。整整一年呢?好吧,让我们看看他最后的编辑:我个人理解他的意思。为了统一时区标准,Java采取了放之四海而皆准的政策。统一标准是以UTC时区1900年之前的任意时刻为标准时间。至于时差……一开始就补上吧。所以,1900-01-0100:00:00加上8小时的时差,就是1900-01-0108:00:00,在此基础上加上27年从1927-12-31那个午夜开始的时间回调带来343秒。1900-01-0108:05:43,个人觉得是这么回事。至于之前stackoverflow中对应的程序,我们现在执行,输出1,但是10年前,输出确实是353,就像我把程序改成这样:最后输出的不是1,而是-342。时间,“倒流”发生了。好吧,又是一个没什么用的知识点。最后,补充两个冷酷的事实。第一个是我在jdkbug列表中追溯,可以发现最早的相关问题是2005年提出的:https://bugs.openjdk.java.net...在这,官方回复是如下:为避免兼容性问题,此问题将不予修复。意思是:问题我明白了,但是这东西不好办,还是先把bug变成feature吧,还是先做吧。别问了,问是有历史原因的。第二个小花絮,前面说了,1927年时区变了,你知道为什么吗?我在一个网站上找到了这段描述:https://zh.wikipedia.org/wiki...1928年,民国十七年。那一年,南昌起义爆发,中国人民解放军成立。那一年,毛泽东在井冈山建立了农村革命根据地。那一年,星星之火化作燎原之势。最后说一句,看到这个就转发,看,点赞,排一个就好了,你都排了我不介意。写文章很累,需要一点积极的反馈。在这里给各位读者朋友敲一下:本文收集自个人博客,欢迎大家来玩。https://www.whywhy.vip/