【问题标题】:Are there actual systems where difftime accounts for leap seconds?是否存在 difftime 占闰秒的实际系统?
【发布时间】:2015-07-09 09:16:45
【问题描述】:

C 标准 (ISO/IEC 9899) 规定:

7.2x.2.2 difftime 函数

概要

   #include <time.h>
   double difftime(time_t time1, time_t time0);

说明

difftime 函数计算两个日历时间之间的差:time1 - time0

退货

difftime 函数以 double 的形式返回以秒为单位的差值。

如果结果说明了leap seconds,这将使其模棱两可(我猜是故意的)。差异(从 1970 年到 2015 年 7 月比较为 26 秒)在某些应用程序中很重要。

C 标准库的大多数实现不考虑闰秒,这是可测试的:以下(故意简洁)代码倾向于输出leap seconds accounted for from 2000/01/01 to 2015/01/01: 0(或-473385600,如果mktime 无效),当有在那段时间里确实有 3 个闰秒。

#include <time.h>
#include <stdio.h>
struct tm t0,t1; // globals, thus initialized to zero
int main(void) {
  t0.tm_year  = 2000-1900;         // from 2000
  t1.tm_year  = 2015-1900;         // to   2015
  t0.tm_mday  = t1.tm_mday  = 1;   // first day of January   
  printf("leap seconds accounted for from 2000/01/01 to 2015/01/01: %.0f\n",
    difftime( mktime(&t1), mktime(&t0) ) - 86400.*(365.*15+4) );
  return 0;
}

是否存在具有 C/C++ 标准库的实际系统,可以使用 mktimedifftime 的组合进行测试?

否则说:许多现代操作系统通过更新机制了解有关法定时间的立法变化,并且像 localtime 这样的标准库函数确实使用该信息并相应地计算其结果。据我所知,完全有可能并且符合 C 标准,类似的更新机制会通知操作系统过去和不久的将来闰秒,并且 difftimemktime 使用该信息。我的问题是问周围是否有这样的系统和标准库,因为这会影响一些代码。


comment 之后:上下文是应该可移植到各种系统(从嵌入式系统到大型机,有些相当老)的代码,并决定何时(从调用时间开始的秒数,最多为 99999 的整数)必须触发一些动作,基于(除了系统时间)给定的“数量”(非闰)“自 2000 年 1 月 1 日午夜 UTC 以来经过的秒数”和所需的动作时间. &pm;2 秒的误差(除了 UTC 参考的漂移)是可以容忍的。

现有代码使用timemktime 表示 2000/01/01 和 difftime 的简单组合来表示它们之间的差异,然后减去给定的值。我想知道是否有严重的担心它可能会失败(并且返回的东西稍微超出了规定的公差;比如在写作时 4 太低了,而且还在增加)。我询问如何使代码可移植(一种选择是使用gmtime(time(NULL)) 并使用显式代码计算其余部分)。

主要问题的措辞是不带time,以排除time是否考虑时区的不同可移植性问题。

【问题讨论】:

  • “差异很大” - 26 秒与 45 年真的微不足道。
  • 这是一个有趣的问题,但是要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack 来说是题外话溢出,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,describe the problem 以及迄今为止为解决它所做的工作。
  • @KarolyHorvath:这本质上是在争论 double 是不需要的,因为 float 具有足够的精度。
  • @Marian:C 标准没有提到 1970 年。我曾使用 C 标准库,其中参考是 1904(MacOS Classic)。 C 标准也没有说明 difftime 的输入是以秒为单位的,以及这些是多少秒(过去 10 天,有 864001 秒,其中一个是闰);我猜想一些 C 标准库使用的单位小于第二个,C 标准肯定允许这样做。
  • @Eregrith:如果您的印象是我要求推荐一个考虑闰秒的系统,那么现在应该清楚的是,情况并非如此;而是我害怕遇到这样的系统。

标签: c++ c portability standard-library


【解决方案1】:

这是一个信息性问题,但实际上是一个物理问题。

第一个信息视图:

常见的操作系统,了解 UTC 时间,最终了解本地时间。他们假设参考是 UTC 时间,并且所有分钟都持续 60 秒。他们使用闰秒来补偿本地时间源(石英)和外部参考之间的误差。从他们的角度来看,滑动时钟的校正和真正的(物理)闰秒之间没有区别。出于这个原因,他们不知道 true 闰秒并且目前忽略它们

现在实物图(参考维基百科上的UTCTAI):

1955 年发明了铯原子钟。这提供了一种比天文观测更稳定、更方便的计时形式。

[1972 年,TAI(Temps Atomique International 法语)被定义,仅基于铯原子钟。] 在 1970 年代,很明显参与 TAI 的时钟由于引力时间而以不同的速率滴答作响膨胀,因此组合的 TAI 标度对应于各种时钟高度的平均值。从儒略日期 2443144.5(1977 年 1 月 1 日 00:00:00)开始,对所有参与时钟的输出进行了修正,以便 TAI 对应于平均海平面(大地水准面)的适当时间。因为时钟平均远高于海平面,这意味着 TAI 减慢了大约万亿分之一。 由于潮汐减速,地球的自转速度非常缓慢地下降;这增加了平均太阳日的长度。 SI 秒的长度是根据星历时间的秒来校准的,现在可以看出它与 Simon Newcomb 分析的 1750 年至 1892 年间观测到的平均太阳日有关。因此,SI 秒接近 19 世纪中期平均太阳日的 1/86400。在更早的几个世纪,平均太阳日短于 86,400 SI 秒,而在最近几个世纪,它超过了 86,400 秒。接近 20 世纪末,平均太阳日的长度(也简称为“日长”或“LOD”)约为 86,400.0013 秒。因此,UT 现在比 TAI“慢”了 1.3 毫秒/天的差异(或“超额”LOD)。

第一次闰秒出现在 1972 年 6 月 30 日。此后,闰秒平均每 19 个月出现一次,总是在 6 月 30 日或 12 月 31 日。截至 2015 年 7 月,总共有 26 个闰秒,均为正数,使 UTC 落后于 TAI 36 秒。

TL/DR 因此,如果您真的需要它,您将必须获取在(物理)UTC 中引入 26 闰秒的日期,并在相关时手动获取。 AFAIK,目前没有操作系统或标准库处理它们。

http://www.ietf.org/timezones/data/leap-seconds.list处以纯文本形式维护了闰秒引入日期的表格

【讨论】:

  • 从信息的角度来看:许多现代操作系统通过更新机制了解有关法定时间的立法变化,并且像 localtime 这样的标准库函数确实使用该信息并相应地计算其结果。这种更新机制完全有可能通知系统过去和不久的将来闰秒,并且difftimemktime 使用该信息。我的问题是问周围是否有这样的系统。
  • @fgrieu :我理解(以及您的实际问题)。正如我在 TL/DR 部分中所说,除了我上次编辑中引用的表之外,我不知道处理该问题的图书馆系统。
猜你喜欢
  • 2013-04-07
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-24
  • 1970-01-01
  • 2010-10-21
  • 1970-01-01
相关资源
最近更新 更多