qakcn
学生会会长
学生会会长
  • 注册日期2008-10-31
  • 最后登录2021-01-05
  • 生日1988-8-18
  • 光玉3394颗
阅读:1308回复:8

科普第21篇——日期时间补遗及计算机的时间

楼主#
更多 发布于:2011-10-14 03:41
国际日期变更线
根据时区的定义,我们知道,地球上肯定有一个时区处于0点(我们这里只说整点的时间),其东边的时区是上一天的日期,其西边的时区是下一天的日期。当这个0点的时区绕地球一圈(这里需要点想象)之后再次回到起点的时候,日期就要加一了。那么这个“起点”在什么地方呢?一般来说定在0度经线的地方最好理解,但是因为0度经线跨过很多陆地,所以为了方便,这条线其实是定在180度经线上,而且为了绕过经线上一些国家(因为一个国家一般是统一时区的),实际上国际日期变更线是条折线。
[IMG]http://p.dmdjz.com/uploads/2011/10/international%2Bdate%2Bline.jpg[/IMG]
但这条线对我们日常计时毫无影响,因为到了0点日期肯定要加一,那么这条线存在的意义何在呢?
其实这条线是为环球旅行者制定的。看过《八十天环游地球》的都知道结局:主角们由于自西向东饶了地球一圈,所以他们计算的天数比出发地的多了一天,因此虽然实际用时是超过了80天,但仍然赢得了赌局。国际日期变更线的作用就在这里:当自西向东穿过变更线时,日期要减少一天,当自东向西穿过变更线时,日期要增加一天。


干支
在时间里,我们提到了稍微提到了以下干支,这里再详细地说一说吧。
所谓干支,就是“天干地支”。
天干有十个:甲乙丙丁戊己庚辛壬癸
地支有十二个:子丑寅卯辰巳午未申酉戌亥
将天干和地支组合起来,就是干支了。
但由于组合时,天干和地支都要增加,比如甲子,下一个是乙丑,而不是甲丑或乙子,所以实际组合出来的干支是60个,而不是120个。这就是“六十一甲子”。
把地支和十二种动物对应,就是我们说的十二生肖了
前面说过,年月日时都可以用干支来表示,就是所谓的“八字”,比如我现在写这篇文章的时间2011年10月14日凌晨1点多,就是辛卯年戊戌月壬寅日辛丑时,用十二生肖来说就是兔年狗月虎日牛时了。俗语里的“猴年马月”就是这么来的。


星期的英文表示的来历
上次我们讲了我国古代星期表示日月火水木金土曜日的由来,拉丁语系的星期表示方法也和这几颗星球有关,这次我们就将讲英文的表示的由来吧。英语里的表示方法是和北欧神话有关的,而这些说法是来自于盎格鲁-撒克孙人(日耳曼民族的几支,移居到不列颠之后通称盎格鲁-撒克孙人,著名的亚瑟王传说就是抵抗盎格鲁-撒克孙人的入侵,英语正是由他们的语言起源的)。
星期日:Sunday,一看就明白了,是和太阳有关的
星期一:Monday,这个也应该比较容易看出来,是与月亮有关的
星期二:Tuesday,来源于北欧神话的战神提尔(Tyr,或译泰尔)
星期三:Wednesday,来源于北欧神话的众神之父奥丁(Woden,也有写作Odin的)
星期四:Thursday,来源于北欧神话的雷神托尔(Thor,或译索尔,著名的雷神之锤就是他的)
星期五:Friday,来源于爱与美的女神,奥丁的妻子弗丽嘉(Frigg,或译弗丽格)
星期六:Saturday,这个有点特殊,不是来源于北欧神话,而是和拉丁语一样,来源于土星(Saturn)


计算机上的时间
我们计算机都有时间的功能,那么这个时间是怎么来的呢?

首先,需要产生基本的时间基准。换句话说,计算机需要知道一秒是多长。这就需要一个元件——石英晶体振荡器,简称晶振。晶振是利用石英晶体的压电效应来产生振荡频率的。
所谓压电效应,就是指当对介质施加电场时,介质会发生形变;当电场移除后,介质形变恢复时又会产生电场(或者对介质施加一个外力时会产生电场),是一种机械能和电能相互转换的现象。
总之晶振就是用来产生振荡频率的了。比如一颗晶振的频率是12MHz,那么可以计算出振荡12M(12,000,000)次的时间就是1秒。

但是,这只是产生了时间的基准,还需要另外一些电路,来记住时间,并且随着时间基准来增加时间。不管是晶振还是用来计时的电路都需要耗电,所以我们可以看到主板上有一颗纽扣电池(当然这颗电池除了给时间电路供电还有给其他的电路供电),当电池没电或取下之后,开机时的时间就不对了,即使我们调整了正确的时间,在关机之后还是会清除。

至于软件里的时间表示,有的程序语言有专门的时间类型(比如Visual Basic,大部分的数据库也有专门的时间类型,而Java之类的面向对象的语言也有时间的类),有的则没有(比如C)。在没有专门时间类型的语言里,通常用整数类型来表示时间。

可以用多个整数来分别表示年月日时分秒。不过今天我们要说一种用一个整数来表示的方式——UNIX时间戳。
看名字就可以知道,UNIX时间戳是UNIX系统开始采用的。

UNIX时间戳表示为1970年1月1日0时0分0秒(UTC)开始计算的秒数,不考虑闰秒。
比如我现在获取的时间2011年10月14日01时51分30秒的UNIX时间戳就是1318528290。

虽然叫做UNIX时间戳,不过现在很多编程语言都支持它,包括微软的.NET架构。
我们浏览网页时经常接触到的cookie的超时过期,采用的就是UNIX时间戳。比如我要设置一个cookie保存一年(比如家族的登录信息),那么我就要获取当前的时间戳并加上31536000(365天的秒数)作为cookie的超时过期时间。


网络时间协议NTP(Network Time Protocol)
如果时间不对了,我们自然要对时。用电视台或广播来对时自然可以,不过考虑到电视和广播在转播过程中的延时(你一定遇到过这种情况——两个不同的台在播放的新闻联播不同步),这种方法并不精确。

其实我们的系统都有内置对时的服务,与时间服务器同步来对时,打开日期与时间属性就能看到了。
[IMG]http://p.dmdjz.com/uploads/2011/10/1-2.gif[/IMG][IMG]http://p.dmdjz.com/uploads/2011/10/eb612f3b2a0dd077d8b43b5a2ffce087.jpg[/IMG]
这个就是通过NTP协议来对时的,NTP协议返回的就是UNIX时间戳,然后再根据时区设置加减计算一下,就能得到当前的时间了。

具体NTP的原理就不说了,也不是这篇文章的重点,这里就告诉大家,中科院国家授时中心的域名是ntp.time.ac.cn(或者IP地址:210.72.145.44),填入上图所示的“服务器”的地方就行了。


千年虫
也就是2000年问题。这个现在虽然已经很少提到了,但是当年还是得到了很大关注。不过当年国内的媒体过分夸大了,有的媒体甚至把这个说成是病毒,那就纯粹是无稽之谈了。
由于这个问题得到很大的关注,所以最终并没有引起严重的问题。

所谓千年虫,是指在过去计算机存储容量还很小的时候,年只用两位来表示,于是2000年会表示为00年,对于一些依赖日期的应用可能会出现计算错误。不过,这是早就已经提出并解决的问题了。比如是用上面的UNIX时间戳就不会遇到这个问题。

但与此问题相似的是,UNIX时间戳会遇到2038年问题,因为现在一般整数都是32位的,表示的正数范围的最大值是2147483647,而这个数字的UNIX时间戳表示的是2038年1月19日3时14分7秒,在此之后就可能出错。当然,解决方法也很简单——改用64位整数就行了。

不过在大家不太关注的2010年,却确实地发生问题了,澳大利亚的银行、Window Mobile系统、赛门铁克的软件都受到了影响。2009年12月31日23时59分59秒之后不是2010年1月1日0时0分0秒,而是跳到2016年1月1日0时0分0秒了。
那么2010年问题又是怎么发生的呢?虽然是题外话,不过还是要说说整数在计算机里的表示。
在科普第3篇和第11篇我们都提到了把十进制整数转换成二进制数来表示的方法。其实十进制数在计算机中还有其他表示方法,这就是BCD码(Binary-Coded Decimal,二进制编码十进制数),用四位二进制数来表示一位十进制数,两位十进制数就要用八位二进制数来表示,三位十进制数就要用12位二进制数来表示(而如果是将十进制数转换成二进制数来表示的话,12位二进制数可以表示0~4096的无符号数或-2048~2047的有符号数)。
而其中一种应用较多的表示方法就是8421码。也就是说四位二进制数的高位到低位分别对应着8、4、2、1。0000表示0,0001表示1,0010表示2,0011表示3,0100表示4,0101表示5,0110表示6,0111表示7,1000表示8,1001表示9。可见8421码的四位二进制数所表示的大小和一位十进制数的大小是一样的,但是最大的就是1001,在往上1010就是非法编码了。因此653的十进制数用8421码表示是0110 0101 0011(而转换成二进制数是0010 1000 1101,为了方便对比在前面补了0)。
2010年问题就是出在这8421码上,2010年的末两位10的8421编码是0001 0000,而程序由于编写时的不严谨,把这个数当作二进制数而不是8421码处理了,而0001 0000换算成十进制数正是16。

不过说到底,不管是2000年问题,还是2010年问题,亦或是2038年问题,都是出在人身上的,计算机是没有错的,计算机只是忠实地执行人们编写的程序而已。但是人不是十全十美的,难免会出错,所以关键地不是怎么样去避免问题发生(当然,不是说就可以放任问题出现),而是在发现问题之后能够合理地解决。

这次又说了好多,算了,就到这里吧,下次估计会开始讲酝酿了很久的网络了。


==========之前的文章==========
科普第1篇——计算机色彩
科普第1篇补遗——CSS颜色
科普第2篇——光盘
科普第3篇——2、8、10、16
科普第4篇——电池
科普第5篇——浏览器
科普第6篇——字符编码
科普第7篇——加密解密
科普第8篇——移动通信技术
科普第9篇——为什么32位CPU不能支持大于4GB内存?
科普第10篇——智能手机简介
科普第11篇——14.52-14.49=0.0299999?
科普第12篇——为什么HTTPS会更安全?
科普第13篇——计算机语言
科普第14篇——字体(上)
科普第15篇——字体(中)
科普第16篇——字体(下)
科普第17篇——域名解析
科普第17篇补遗——域名
科普第18篇——虚拟内存
科普第19篇——时间
科普第20篇——日期

科普番外篇1——虽然没用但了解一下也很有趣的知识
喜欢0 评分0
bleen
光坂学士生
光坂学士生
  • 注册日期2010-05-28
  • 最后登录2022-02-21
  • 生日1988-12-9
  • 光玉2111颗
沙发#
发布于:2011-10-14 03:45
话说,PHP里面的时间函数貌似默认不是北京时间?
回复(0) 喜欢(0)     评分
火舞
学生会干部
学生会干部
  • 注册日期2011-06-12
  • 最后登录2021-10-03
  • 生日1991-11-10
  • 光玉2007颗
2楼#
发布于:2011-10-14 08:57
于是双系统的正在纠结时区问题中- -
回复(0) 喜欢(0)     评分
diehell
光坂学士生
光坂学士生
  • 注册日期2011-02-12
  • 最后登录2014-07-19
  • 生日1977-12-15
  • 光玉2090颗
3楼#
发布于:2011-10-14 09:45
好帖子 收藏起来
回复(0) 喜欢(0)     评分
esc
esc
光坂学士生
光坂学士生
  • 注册日期2011-10-05
  • 最后登录2020-05-31
  • 生日1993-4-7
  • 光玉2440颗
4楼#
发布于:2011-10-14 09:50
感觉很难懂的说~
回复(0) 喜欢(0)     评分
梦幻的夏
光坂学士生
光坂学士生
  • 注册日期2008-10-29
  • 最后登录2014-08-21
  • 生日1986-4-15
  • 光玉3005颗
5楼#
发布于:2011-10-14 20:49
大扣你上知天文下晓地理,古今中外无所不知了。
回复(0) 喜欢(0)     评分
serffyme水草~
光坂学士生
光坂学士生
  • 注册日期2008-12-11
  • 最后登录2020-04-28
  • 生日1989-11-27
  • 光玉4876颗
6楼#
发布于:2011-10-14 22:04
没想到一个时间显示都有那么多讲究。。0 0
没拆过电脑呢~也没看过那颗小纽扣~
回复(0) 喜欢(0)     评分
甜瓜包制作大师
学生会干部
学生会干部
  • 注册日期2009-11-29
  • 最后登录2021-10-09
  • 生日1994-1-6
  • 光玉3410颗
7楼#
发布于:2011-10-14 22:07
本面包师之前听说2038年问题还是看命运石之门引申出来的呢
回复(0) 喜欢(0)     评分
梦幻的夏
光坂学士生
光坂学士生
  • 注册日期2008-10-29
  • 最后登录2014-08-21
  • 生日1986-4-15
  • 光玉3005颗
8楼#
发布于:2011-10-16 20:36
据说只要把纽扣电池取下重装过,开机密码就也会无效,这也是因为时间的关系?
回复(0) 喜欢(0)     评分
游客

返回顶部