首先我们先明确时间的概念,简单的说,计算机界有个协调世界时:即1970年1月1日0时0分0秒,之后的时间就是从此时间起的总秒数,再换算出当前的时间。
很多朋友都会记得2000年的千年虫问题,可是用C语言编制的程序不会碰到。这是因为,大多数C语言程序都使用到一个叫做“标准时间库”的程序库,这个时间库用一个标准的4字节也就是32位的形式来储存时间信息。4字节32位的存储空间,到2000年不会有溢出的现象。
但是请注意!4字节也就是32位的存储空间其最大值用二进制表示为:01111111 11111111 11111111 11111111,即十进制的:2147483647。
当时间一秒一秒地跳完2147483647,二进制表示为在下一秒二进制数字会是10000000 00000000 00000000 00000000,这是负数。所以2147483647那惊心动魄的最后一秒后,你猜怎么样?此时系统的时间会溢出。时间将会被重置。
时间真的是个大问题, 2038年1月19日3时14分07秒,总秒数正好是2147483647,达到32位元系统存储的极限,时间将会被重置。因此系统会把时间误解作1901年12月13日20时45分52秒(亦有说回归到1970年)。这可能会令软件发生问题,导致系统瘫痪。
当前世界大部分使用UNIX的系统都是32位元的,即它们会以32位二进制数字表示时间,所有使用POSIX时间表示时间的程序也是以32位表示时间的,也都将受其影响。
如何解决呢?那就是升级使用64位的系统时间,其二进制数字表示时间的系统(最多可以使用到格林威治时间292,277,026,596年12月04日15时30分08秒)则基本不会遇到这类溢出问题。 有兴趣的朋友可以看看自己的计算机是多少位的,试试把你的计算机系统时间改为2038年1月20日,试试看,各种软件的运行情况如何呢,很有意思的啊,但有一定风险。
好了,下面在GO语言的时间包里进一步解读上述问题:
1 package main
2
3 import "fmt"
4 import "time"
5
6 func main() {
7 fmt.Println(time.Now())
8 fmt.Println(time.Unix(2147483647, 0))
9 fmt.Println(time.Unix(0, 0))
10 fmt.Println(time.Now().UnixNano() / 1e9) //将纳秒转换为秒
11 time1 := time.Date(2038, 1, 19, 11, 14, 7, 0, time.Local) // 6-1-2-3-4-5,GO生日
12 fmt.Println(time1)
13 unix_time := time1.Unix()
14 fmt.Println(unix_time)
15 }
截图:
图1
输出:
图2
好了,将此文写道这里就到一段落,但是细心的朋友会看到,GO语言解读出来的时间是2038年1月19日11时14分07秒,和上文中说道的2038年1月19日3时14分07秒,不一致,为什么呢?有兴趣的朋友互动一下。
分享成果,随喜正能量
领取专属 10元无门槛券
私享最新 技术干货