Recollect的黑色世界...... 注册 | 登陆

闰秒(leap second)和linux/unix时间

本广告位招商中!联系邮箱heiqu8#163.com,将#替换为@...

闰秒(leap second)和linux/unix时间

2小时前

  以前只知道有闰年,最近听说了一个新名词,叫闰秒。因为它造成了我工作中的一个模块的crash,经过不懈的google + wikipedia,终于了解了一二,在这里简单分享一下。

  一. 闰秒的由来

  在现有的世界时间体系中,存在多种标准,然而用得最多的就是世界时和原子时了。世界时是根据地球自转为准的时间尺度,然而由于多种因素影响,因此地球自转并不稳定,导致世界时也不是均匀的时间尺度。以原子震荡周期为基础,并由世界度量衡局以世界各国家实验室原子钟群加权平均产生之时间尺度称为国际原子时。原子时相对世界时稳定,因此经过一段时间以后,国际原子时与世界时渐渐产生了不一致。为了使生活中之自然时刻能与原子时相符合,国际另外从国际原子时(TAI)引出一计时方式,称为协调世界时(UTC),作为最终之国际时刻标准。此方式早期采用原子频率偏调,到公元一九七二年七月一日首次改用闰秒调整,当世界协调时(UTC)与一号世界时(UT1)之差(Difference UT1, DUT1)的绝对值预期在半年或一年之内将超过0.9秒时,为保持DUT1在0.9秒内,国际地球自转组织(International Earth Rotation Service, IERS)便会发布闰秒通告。在当年12月31日或6月30日的最后一分钟(UTC时间,换算北京时间为次年1月1日上午7时59分或7月1日上午7时59分)做闰秒调整。增加一秒时为正闰秒,减少为负闰秒。如果这一秒是被加载第二天的00:00:00前,则当决定加入正闰秒时,当天23:59:59的下一秒当记为23:59:60,然后才是第二天的00:00:00。如果是负闰秒,23:59:58的下一秒就是第二天的00:00:00了。

  值得注意的是原子时(TAI)与世界时(UT1)分别来自于两个互不相干的系统,虽然

  协调时(UTC)基本上解决了两者之间的协调问题,但是由于地球自转速度越来越慢加之不均匀,按照目前情况,不能排除若干年后出现一年闰几次甚至更多次秒

  的可能性。因此IERS发布闰秒公告的时间也是不定的。

  二. linux/unix下的时间函数

  这个只是简单介绍一下。

  1. 时间是通过一个预定义类型time_t来处理,在linux系统中,它是一个长整型,与处理时间值的函数一起被定义在头文件time.h中。

  相关的时间值处理函数:

  2. time_t time(time_t *tloc);这个函数可以返回从纪元(GMT 1970年1月1日午夜0点)至今的秒数。如果参数tloc不是空指针,函数还会把返回值写入tloc指向的位置。

  3. double difftime(time_t time1, time_t time2);用于计算两个时间值之间的差。

  struct tm* gmtime(long* clock);函数原型为struct tm* gmtime(const time_t* timep);是用于把日期和时间转换为格林威治(GMT)时间的函数。其中tm结构定义如下:

  struct tm

  {

  int tm_sec; /* Seconds. [0-60] (1

  leap second) */

  int tm_min; /* Minutes. [0-59]

  */

  int tm_hour; /* Hours. [0-23] */

  int

  tm_mday; /* Day. [1-31] */

  int

  tm_mon; /* Month. [0-11] */

  int

  tm_year; /* Year - 1900. */

  int tm_wday; /*

  Day of week. [0-6] */

  int tm_yday; /* Days in year.[0-365]

  */

  int tm_isdst; /* DST. [-1/0/1]*/

  #ifdef __USE_BSD

  long int tm_gmtoff; /* Seconds east of UTC.

  */

  __const char *tm_zone; /* Timezone abbreviation.

  */

  #else

  long int __tm_gmtoff; /* Seconds east of UTC.

  */

  __const char *__tm_zone; /* Timezone abbreviation.

  */

  #endif

  };

  这里值得注意的是tm_sec,范围允许闰秒和双闰秒。

  4. struct tm* localtime(const time_t* clock);是把纪元到当前的系统所偏移的秒数时间转换为日历事件;相比上一个函数,它返回的结构中包含的值已根据当地时区和是否采用夏令做了相应的调整。

  5. 还有两个输出更加友好的时间函数asctime和ctime,这里就不再赘述了。

  三. 操作系统中的闰秒(leap second)

  1. 对于大多数新的linux内核,在设计时它们都是支持闰秒的,这一点在REHL4/5 的2.6.x内核中得到肯定。

  2. 如果linux系统没有配种某种时间同步机制(比如NTP),那么和闰秒无关,唯一导致的结果只是系统时间会比UTC时间快一秒。

  3. Window Time Service不支持闰秒,包括服务器和客户端。

  引用了这么多资料,只为说明闰秒很重要,一不小心可以会影响我们系统的正常工作,如果底层模块不支持闰秒,抛出了异常信息,上层也要注意捕获,否则会导致系统crash,就像我工作中的模块一样。



原文地址:http://user.qzone.qq.com/66869330/blog/1276341815

如页面无法正常浏览,请查看原文地址!如有版权争议请与站长联系!我们会尽快删除相关网页快照!

« 上一篇 | 下一篇 »

Trackbacks

点击获得Trackback地址,Encode: UTF-8

发表评论

评论内容 (必填):