用python体验2038年问题

通过计算器看一下4字节能表示的最大数值,(windows默认好像是signed类型,没有找到可以设置unsigned的地方)不过这不影响我们的测试,因为还有qword类型:


最高位为符号为,0表示正数,1表示负数,所以4字节能表示的最大正数是0x7FFFFFFF。将数字取反,就是最小的负数:


结果是0x80000000,十进制就是-2147483648,那如果是无符号呢?将类型设置为QWORD,然后将四个字节全部填充为0:


0xFFFFFFFF化成整数就是4294967295。接下来正式看一下python中关于2038溢出是怎么处理的。查看wiki资料说64位系统上的软件已经将time_t类型扩展为128位了,碰巧现在电脑上安装的python还是32位,所以先做个对比,如下先定义一个utc和ntp时间,分别从1970.1.1和1900.1.1日开始:


给utc加上0x7FFFFFFF秒,也就是4字节signed整数所能表达的最大正整数值,看一下结果:

可以看到有符号4字节所能记录的最大utc时间就是2038年1月19日,3时14分7秒。不过为了弥补这个问题,现在python32位版本已经将时间类型转换为了无符号类型,重新测试:

0xFFFFFFFF表示的有符号整数为-1,而无符号整数为4294967295,从python32位版本处理结果来看,已经将这个字段当作无符号数来处理了。这就有另外一个问题了,因为ntp时间的timestamp类型是有64个bit构成的(前32bit表示多少秒,后32bit表示多少个232皮秒),这样一来,ntp的timestamp类型所能表达的日期就很小了:

也就是说到了2036年2月7日6时28分15秒以后,ntp的timestamp就将归零吗!重新将python3 32位版本删除,换成最新的64位版本试一下:

结果还是一样,超过0xFFFFFFFF都会提示out of range,在64位Ubuntu上测试也是一样的提示。那如果将datetime初始化为未来5000年的时间,效果是什么样的呢:

可以看到,datetime可以无误的承接未来的时间,不会出现问题。

发表评论

电子邮件地址不会被公开。 必填项已用*标注