问题标签 [tai-time]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 如何在 Java 中获取 GPS 时间和 TAI 时间?
(System.currentTimeMillis()
的返回值是 POSIX 时间,它不是时间的线性表示。)
java - 如何在 Java 7 中获取国际原子时间
我正在做一个 Java7 项目,我们需要一个国际原子时间的时间戳。我发现了一些与此相关的其他问题,这些问题指向 JSR-310 和 ThreeTen 项目(正在实施 JSR-310):
http://www.coderanch.com/t/549178/java/java/TAI-Atomic-Time-International
但是,我正在努力弄清楚 Java 7 使用什么以及从哪里获取它。ThreeTen 似乎有旧的 SourceForge 和 GitHub 页面,以及一个 OpenJDK 页面。
我找到了 Java 7 backport,但是从 Maven 下载它后,它不包含我真正需要的 TAIInstant 类(TIAInstant 类在 ThreeTen SourceForge JavaDoc 中的 javax.time.TAIInstant 下列出)。
为了完整起见,这是我的 pom.xml 的摘录:
我应该使用其他东西,我应该从哪里得到它?
注意:抱歉,我无法提供指向我所指的所有页面的链接,StackOverflow 不会让我在没有更高代表的情况下每个帖子有 > 2 个链接。
[编辑]
想要 TAI 的原因是我需要一个单调递增的时间戳,我相信 TAI 满足(即使在正负闰秒期间,因为它不关心闰秒,所有秒数都一样,包括闰秒)。
从各种来源阅读了有关 POSIX / Unix 时间的信息后,我仍然不清楚 Unix 时间在闰秒内到底发生了什么。我知道 Unix 时间在指代 UTC 时间方面是模棱两可的,但我不清楚在闰秒发生的那一刻 Unix 时间会发生什么?例如,Unix 时间会“暂停”还是倒退?也许更重要的是,即使它不应该根据 Unix 时间规范,Unix 实现是否真的遵守关于闰秒的规范......?
最后,我是否正确地说 System.currentTimeMillis() 将获得相当于 POSIX 时间(尽管以毫秒而不是秒为单位)?
注意,我需要一个可跨 JVM 和机器移植的对象(排除 System.nanoTime() 或类似的)。
[结论]
TAI
TAI 是一个测量时间的系统,其中每一秒都被计算并且“所有秒数都相等” - 即。每一秒包含相同的时间段,所有秒(包括闰秒)都计入总秒数。这意味着 TAI 中的秒数(从某个任意起点开始计算,例如 Unix 纪元)是一个单调递增的整数。
POSIX 时间
POSIX 时间是测量时间的标准(不是实现)。它将每一天定义为恰好有 86400 秒。因此,POSIX 时间不计算闰秒(因为偶尔一分钟可能有 61 秒,导致天数 >86400 秒,理论上一分钟可能有 59 秒,导致天数 <86400 秒)。这意味着 POSIX 中的“秒”具有可变长度,并且在闰秒之前/期间/之后不久,POSIX 时钟可能会跳过几秒或重复它们。具体来说,Meno Hochschild 在他的回答中引用的 POSIX 规范指出:“自 Epoch 以来的实际时间与当前秒数之间的关系是未指定的。”
UTC
UTC 是与地球围绕太阳运动的方式有关的时间标准,旨在保持太阳位置与一天中的时间(在阈值内)之间的关系。即在地球的 UTC+0 区域,太阳总是在 UTC 时间的中午处于最高位置。闰秒(正或负)是必要的,因为地球自转的速度不是固定的,并且它不会以可预测的方式变化(这意味着我们无法预测何时需要闰秒 - 或者它们是正闰秒还是负闰秒)
代表时间
在我看来,TAI 和 POSIX 都是“秒数”的表示(即计算机实际存储的容易的东西),而 UTC 是时间的“人类解释”(即年/月/日Hour:Minute:Second.millisecond) 通常不由计算机内部存储。
翻译时间
鉴于上述情况,从 POSIX(不计算闰秒)到 TAI(计算闰秒)存在许多问题:
- 它需要维护一个表/闰秒计数来将任何 POSIX 时间转换为 TAI 时间
- 即使解决了第 1 点,上述 POSIX 规范也不能保证闰秒期间会发生什么,因此在这种情况下,我们无法准确表示一个明确的时间
- 如果多个系统必须通信,在它们之间传递时间戳,我们必须保证闰秒表/计数保持一致
另一方面,很容易从 POSIX 转换为 UTC 的“人类解释”。它不需要闰秒的知识,因为它只是假设每天都有相同的秒数(尽管其中一些“秒”实际上具有不同的时间长度)。在实践中,您只需使用 POSIX 规范中公式的倒数来获得各种 UTC 时间分量(再次,请参阅 Meno Hochschild 引用的 POSIX 规范)。
java - 如何获取当前TAI时间?
如何在 Linux 中使用 Java 或 C++ 获取当前 TAI 时间(以毫秒为单位)?
我需要这个的原因是能够在很长一段时间内(以年为单位)准确地获取时间戳,并且仍然能够比较它们,而不必担心闰秒。在闰秒期间可能会发生多次测量,并且所有测量都需要是明确的、单调递增的和线性递增的。这将是一个专用的 Linux 服务器。这是一个需要大约 0.5 秒精度的科学项目。
我目前不希望投资 GPS 计时器,并希望使用 NTP 连接 pool.ntp.org 以保持系统时钟正常运行。
我研究了以下解决方案:
Java 8 或 ThreeTen 项目 获得 TAIInstant 的唯一方法是使用 Instant 然后对其进行转换,根据规范,“根据 UTC-SLS,从 Instant 转换在闰秒附近不会完全准确。 " 这本身没什么大不了的(事实上,使用 UTC-SLS 也是可以接受的)。但是,在 Instant 类中使用 now() 似乎也只是 System.currentTimeMillis() 的包装,这让我觉得在闰秒期间,时间仍然会模棱两可,项目实际上不会给我 TAI 时间. Java 8 规范还规定:
使用 JSR-310 API 的 Java 时间刻度的实现不需要提供任何亚秒级精度的时钟,或者单调或平滑的时钟。因此,实现不需要实际执行 UTC-SLS 转换或以其他方式了解闰秒。
使用对/?timezone 这似乎可行,但是我不确定实现是否足够聪明以在闰秒期间继续工作,或者 System.currentTimeMillis() 是否甚至会给 TAI 时间。换句话说,底层实现是否仍然使用 UTC,从而在闰秒期间给出一个模棱两可的时间,然后将其转换为 TAI,或者使用正确/时区是否始终使用 System.currentTimeMillis() 与 TAI 一起工作(即即使在闰秒)?
使用 CLOCK_TAI 我尝试在 Linux 内核中使用 CLOCK_TAI 但在我的测试中发现它与 CLOCK_REALTIME 完全相同: 代码:
输出很简单:
使用 CLOCK_MONOTONIC这样做 的问题是,即使计算机重新启动,时间戳也需要保持有效和可比较。
time - 为什么 UTC 最初定义为从 TAI 偏移 10 秒
来自http://derickrethans.nl/leap-seconds-and-what-to-do-with-them.html
UTC 被定义为(在其定义的最新调整中)与 TAI 相差 10 秒,使得 1972-01-01T00:00:00 UTC 和 1972-01-01T00:00:10 TAI 在同一时刻。
来自https://en.wikipedia.org/wiki/International_Atomic_Time
TAI 正好比 UTC 早 36 秒。36 秒是 1972 年初 10 秒的初始差异加上自 1972 年以来 UTC 的 26 闰秒的结果。
为什么初始相差 10 秒?
c - CLOCK_TAI 的纪元是多少?
从 Linux 内核版本 3.10 开始,该功能clock_gettime()
现在接受CLOCK_TAI
.
我没能找到这个时钟的详细描述。它的时代是什么?
编辑 1:刚刚比较了我的 Linux 3.19 操作系统上的 CLOCK_REALTIME 和 CLOCK_TAI 的输出,它返回完全相同的值(1442582497)!?CLOCK_REALTIME 是否在闰秒减少?
编辑 2:根据这篇文章, CLOCK_TAI 和(名字不好的) CLOCK_REALTIME 之间的区别应该是闰秒数。
编辑 3:编辑 2 中引用的文章解释了原因CLOCK_TAI
和CLOCK_REALTIME
时间相同。重点是我。
对于可以使用 TAI 时间而不是 UTC 的应用程序,内核提供了一个特殊的 CLOCK_TAI 时钟,它确实包括闰秒并且不需要在闰秒之后进行校正,从而完全避免了时间向后跳跃的问题. 它被实现为以相对于 CLOCK_REALTIME 的固定积分偏移量运行的时钟,当 CLOCK_REALTIME 时钟在闰秒后退时,该时钟以原子方式递增 1。它是在 Linux 内核版本 3.10 中引入的,并且随 RHEL7 中的内核一起提供。请注意,CLOCK_REALTIME 的偏移量在启动时被初始化为零,并且 ntpd 和 chronyd 都没有将其默认设置为正确的值(当前为 35)。在应用程序中切换到 CLOCK_TAI 当然需要修改代码,可能还需要修改所有使用 Unix 时间表示的协议。
编辑 4:在 Ask Ubuntu 上获得的这个答案澄清了一切。
java - 在 Java 中查找自 2004 年 1 月 1 日 00:00:00 UTC 以来的 TAI 秒数
正如标题所述,我需要找到自 2004 年 1 月 1 日 00:00:00 UTC 以来的TAI 秒数(在 Java 中)。我最近才知道 TAI 是什么,而我尝试解决上述问题让我有点困惑。
我试过的:
我知道在 Java 中,您可以使用System.currentTimeMillis()
自 1970 年 1 月 1 日 UTC ( Javadocs ) 以来的毫秒数。
此外,从我对原子时间的简短研究中,我了解到目前 TAI 正好比 UTC 早 37(闰)秒。
因此,我的思考过程是:
- 求 1970 年到 2004 年(34 年)之间的秒数
- 从当前 UTC 时间中减去它,得到自 2004 年以来的数量
- 加 37 得到 TAI 中的实际秒数
我不确定这里的数学(1 天 = 86400 秒):
- 选项 1:86400(秒)x 365.25(天(1 儒略年))x 34(年)= 1,072,958,400
- 选项 2:86400(秒)x 365(天(1 个共同年份))x 34(年)= 1,072,224,000
在这一点上,我开始质疑添加到 TAI 的 37 闰秒与 UTC 相比是否要考虑闰年,因此我应该使用Option 2。不幸的是,我不确定我的思维过程是否正确,我认为最好在这里问一下。
此外,我发现这个引用声称1,072,915,200(秒)相当于01/01/2004 @ 12:00am (UTC)。哪种让我失望,因为它不等于我的任何一个计算。
java - 将 TAI 时间转换为 Java Instant
我可以使用秒和纳秒访问 TAI 时间 - 让我称之为T
。
我现在想创建一个Instant
对应于这个值的 java 类T
。
我一直在寻找合适的构造函数来做到这一点,但没有运气。