您的位置:知识库 » 编程基础

关于时间,每个程序员都应了解的事

作者: Emil Mikulic  来源: 伯乐在线  发布时间: 2013-01-27 15:05  阅读: 5926 次  推荐: 9   原文链接   [收藏]  

  英文原文:Some notes about time

  注:英文原文由 @程序员的那些事 在微博推荐,感谢 @泉州一中-刘家昌 编译完成初稿。在译文基础上,伯乐在线根据维基百科等资料有补充和改动。也感谢 @周金宇Jered 的翻译。(如需转载,请保留本段说明。)

  一些关于时间的注解:

  ● UTC/协调世界时:又称“世界标准时间”或“世界协调时间”,简称UTC(从英文“Coordinated Universal Time”/法文“Temps Universel Cordonné”而来),是最主要的世界时间标准,其以原子时秒长为基础,在时刻上尽量接近于格林尼治平时。中国大陆称之为“协调世界时”。台湾称之为“世界統一時間”。

  ● GMT(Greenwich Mean Time):是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。格林尼治时间(GMT)曾经作为标准时间使用,但因地球自转不规则的原因,GMT 已不再作为现在的标准时间,现在的标准时间是由原子钟报时的协调世界时(UTC)。


  设于英国格林尼治皇家天文台大门外的24小时制电子大钟,显示格林尼治标准时间。

  ● 其他时区都可写为与 UTC 时间的偏移量。北京时间是 UTC+8(俗称“东八区”)。例如某日的 UTC 00:00  是同日的北京时间 08:00。

  ● 夏令时并不影响 UTC。它只是当地政府关于改变其时区(与 UTC 的偏移量)的决定。 例如,GMT 在冬季是英国的国家时区,而夏季则选用英国夏令时(BST)。

  ● 闰秒:根据国际惯例,通过在每个 UTC 年的十二月,或者六月的最后一秒,引入一秒闰秒,来使 UTC 与物理现实(UT1,天文时间量度)保持 0.9 秒以内的差距。(UTC 完全是人类武断的定义,而平均太阳日的长度正以非常缓慢的速度增加中)

  ● 闰秒并不需提前六个月宣布。这对于时长超过六个月的精密时间计划是重大的问题。

  ● Unix 时间:亦或称 POSIX 时间,以 Unix 纪元初(1970年1月1日0时0分0秒)至今的总秒数度量,不包括闰秒。 Unix 时间不受时区和夏令时的影响。

  2038年1月19日3时14分07秒,32位系统的UNIX时间将会被重置

  ● 根据 POSIX.1 标准,Unix 时间应该通过重复前一秒处理闰秒。例如:

59.00
59.25
59.50
59.75
59.00 ← 重复
59.25
59.50
59.75
00.00 ← 增加
00.25

  这一方法有利有弊:你无法重现一个闰秒,而且时间可能会倒退;但从另一个角度来说,每天的时间却确切为 86,400 秒长,输出人类可读的时分秒之时,你并不需要列出一个过去和未来的所有闰秒表。

  ● ntpd (Network Time Protocol daemon)在从上流服务器处接收到“闰秒位(leap bits)”后,应当完成这次时间重复。 但我也曾见过它违背这一标准:系统进入到未来的一秒,然后缓慢地偏移回正确的时间。

  每个程序员都应了解的关于时间的事:

  ● 时区是一个表示层的问题!  你多数的代码不应处理时区或本地时问题,请总使用 Unix 时间。

  ● 使用 Unix 时间作为度量,它是 UTC 时间 —— 易于获取,而且没有时区、夏令时(和闰秒)。

  ● 保存时间时使用 Unix 时间,它是一个整数。

  ● 如果你希望保存人类可读的时间(例如在日志中),考虑将其与 Unix 时间共同保存, 而不是取代 Unix 时间。

  ● 显示时间时,同时显示所在时区——一个未知时区偏移量的时间是无用的。

  ● 系统时钟并不精确。

  ● 你在一个网络中? 那么请注意所有系统的时钟都有不同的不精确性。

  ● 系统时钟可以——或者会——因你所控制外的事情向后或向前跳跃。你的程序必须能够处理这一问题。

  ● 每[实际]秒的[时钟]滴答并不精确且易变。多数情况它会随温度而变化。

  ● 不要盲目地使用 gettimeofday()。如果你需要一个单调递增的时钟,选择clock_gettime().

  ● ntpd 可以通过以下两种方式改变系统时间:

  +跳跃: 直接将系统时钟即时地向前或向后调整为正确时间。

  +转换: 修改系统时钟的频率,使系统时间慢慢地偏移为正确时间。

  转换这一方法破坏性较小,因而它较受欢迎。但只当修复小的时间误差时此方法才有效。

  值得一提的:

  ● 根据相对论,每个“观察者”的“一秒钟”都是不同的。远程时钟频率相对一个“观察者”来说,受到相对速度和重力的影响。GPS 卫星中的时间已根据相对论效应调整。

  ● MySQL(高于 4.x 和 5.x 的版本)将 DATETIME 类型保存为一个 “YYYY-MM-DD HH:MM:SS” 串的二进制编码。其本身并不保存时差,使用时根据 @@session.time_zone 指示时区解释。

mysql> insert into times values(now());
mysql> select unix_timestamp(t) from times;
1310128044
mysql> SET SESSION time_zone='+0:00';
mysql> select unix_timestamp(t) from times;
1310164044

  如果你很介意这件事,那么使用 UNIX_TIMESTAMP() 和 FROM_UNIXTIME() 函数,将时间保存为数字。(UNIX_TIMESTAMP() 将参数时间串使用当前 time_zone 的设定解释,并转换为 Unix 时间数字,如果当地规定了夏令时,也将按夏令时解释)

  还有 TIMESTAMP 类型,将时间保存为 Unix 时间。它有不同的用法

9
0

编程基础热门文章

    编程基础最新文章

      最新新闻

        热门新闻