问题 1984年3月16日发生了什么?


我想弄清楚1984年3月16日有什么特别之处。在我使用的虚拟机上(没什么特别的),Python(以及 PyPy)当试图使用mktime时,崩溃似乎是一个非常合理的时间结构。

$ pypy
Python 2.7.3 (f66246c46ca30b26a5c73e4cc95dd6235c966b8f, Jul 30 2013, 09:27:06)
[PyPy 2.0.2 with GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>> import time
>>>> time.mktime((1984,3,16,0,0,0,0,0,0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: mktime argument out of range
>>>> time.mktime((1984,3,15,0,0,0,0,0,0))
448156800.0
>>>> time.mktime((1984,3,17,0,0,0,0,0,0))
448326000.0
>>>> time.mktime((1984,3,16,0,0,0,0,0,0))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: mktime argument out of range
>>>> 

为什么以及可以采取哪些措施来避免这个问题?

虽然问题确实每次都发生在这个VM上,但我无法让它在任何其他VM上发生。


7114
2017-09-23 02:29


起源

奇怪。不会在我的机器上出现问题(Mac OS,Python 2.7)。 - Floris
我认为这可能是闰秒,但1984年(在任何一个日期)都没有添加 en.wikipedia.org/wiki/Leap_second 。我怀疑你的Python版本中有一个错误... - Floris
没有什么可以添加除此之外我也没有问题。很奇怪。 - verbsintransit
@ShashankGupta:事实上它归结为系统问题。 “date -d 03/16/1984”返回“无效日期。但仍然很奇怪。 - Benoît
你的时区是几号? - falsetru


答案:


啊哈!神秘解决了(因为OP终于找出了“出错”的时区)。我找到了这个:

http://www.timeanddate.com/worldclock/timezone.html?n=60&syear=1980

1980    No time changes  
1981    No time changes  
1982    No time changes  
1983    No time changes  
1984    Time zone change on Friday, March 16, 1984 at 1:00:00 AM     
1985    Time zone change on Tuesday, December 31, 1985 at 11:00:00 PM    
1986    No time changes  
1987    No time changes  
1988    No time changes  
1989    No time changes  

所以,我猜“1984年3月16日发生的事情”的答案是卡萨布兰卡当天凌晨1点改变了时间。 :)

从技术上讲,它立即从午夜跳到凌晨1点,所以从00:00开始到01:00之前的所有时间都会产生相同的错误。也就是说,我猜是这样的 time.mktime((1984,3,16,1,0,0,0,0,0)) 更大的将工作,但例如, time.mktime((1984,3,16,0,59,0,0,0,0)) 将不会。


7
2017-09-23 11:50



因此,3月15日至16日之间从未有过午夜(午夜瞬间变为凌晨1点),这就是为什么不能构建特定时间的原因。 - Damien_The_Unbeliever
你知道,如果这个问题被标记了 timezone 从一开始(特别是如果它没有 python 标签,可能),然后Jon Skeet本来就是这个。在这里看到奇迹般的答案: stackoverflow.com/questions/6841333/... - John Y


鉴于448326000.0和448156800.0之间的差异为47小时而不是48小时,您的机器认为1984年3月15日午夜到1984年3月17日午夜之间有夏令时过渡。

但据我所知,法国当天没有发生这种转变。而且我不确定你如何修复操作系统对历史性夏令时转换的解释。


7
2017-09-23 06:01



更改时区(错误设置为卡萨布兰卡)解决了问题......或者转换为另一个未知日期,谁知道! - Benoît
哇,有人关心实际检查结果和 做 他们的东西!太好了!只有这一点值得我的支持,即使它不是OP问题的真正解决方案。希望它至少会提供一些最终会导致真正答案的线索。本着这种精神,我想建议OP尽量缩小时间范围。 1984-03-16全部搞砸了,还是特定时刻?夏令时是一个很好的猜测,但令人难以置信的奇怪(按美国标准),因为该日期是星期五,我们的夏令时总是在星期日开始/结束。 - John Y
啊,当我在输入评论时,OP发布了一个决议(虽然不能解决这个问题)。我想对@falsetru赞不绝口,因为他确实询问了时区。 - John Y