std::chrono::system_clock.now().time_since_epoch().count() 的值是不是单调增加?

Posted

技术标签:

【中文标题】std::chrono::system_clock.now().time_since_epoch().count() 的值是不是单调增加?【英文标题】:Does the value of std::chrono::system_clock.now().time_since_epoch().count() increase monotonically?std::chrono::system_clock.now().time_since_epoch().count() 的值是否单调增加? 【发布时间】:2019-12-08 05:22:14 【问题描述】:

我知道steady_clock 并且它是唯一指定为单调的时钟。而且我知道system_clock 由于夏令时和闰年可以向前或向后跳跃。但是count() 不是给你自 Unix 纪元以来系统时钟的滴答数,这是一个一直在增加的数字,无论整数的滴答数如何被解析为“日历日期 + 挂钟”解释? 即使“日历日期+挂钟”在三月的某一天从凌晨2点跳到凌晨3点,刻度的整数计数不是只增加了一个刻度吗?

简而言之,难道std::chrono::system_clock.now().time_since_epoch().count() 的值在短期内会单调增加(当然,除非系统时钟更新是一个非常真实的事件),即使它所指的日期+时间跳来跳去?

编辑

正如@SergeyA 所指出的,如果系统时钟发生变化,那么值当然会跳来跳去。但我认为由于夏令时而导致的挂钟时间变化不是 NTP 更新事件或用户手动更改。如果它有助于澄清问题,我对可能跨越 DST 边界的一两个小时的正常运行时间感兴趣,而不是时钟可能漂移的几周或几个月的正常运行时间。

【问题讨论】:

如果时间从凌晨 2 点到凌晨 3 点,计数是秒,它怎么可能只增加一?它是从凌晨 2 点或 3 点开始的秒数。 但是如果date+time的底层表示是整数秒,那么从1970-01-01 00:00:00到2019-03-10 03:00的秒数: 00 只是 1 + n,其中 n 是从 1970-01-01 00:00:00 到 2019-03-19 01:59:59 的秒数。 不是重复的问题,但它也回答了这个问题:***.com/questions/27365236 计数不会因为夏令时或闰年而改变。它会发生变化,因为没有时钟能保持完美的时间,如果你想让你的时钟相对于 UTC 保持准确,你必须偶尔调整它。 【参考方案1】:

system_clock 跟踪 Unix Time。 Unix Time 没有 UTC 偏移调整(夏令时)。它只是非闰秒的线性计数。在闰秒插入期间,实现可能会向后跳转。虽然在实践中闰秒在几个小时内被许多微小的调整“涂抹”了。

理论上,system_clock 可能是单调的。在实践中,没有时钟可以保持完美的时间,并且必须调整(可能向后)以与 Unix Time 保持同步。

在 C++11/14/17 中,没有为 system_clock 指定 Unix Time 度量,但这是现有的做法。在 C++20 中,it will be specified。

【讨论】:

我在其他地方对 SergeyA 的评论中描述了我的 XY 问题的性质,但我仍然认为原始问题有其优点,而且我认为您的答案是我所寻找的。读完后,我意识到闰秒可能是一个红鲱鱼;我应该把它们排除在外,但由于这个答案,我现在更好地理解了它们。谢谢!【参考方案2】:

简短的回答 - 不,它没有。作为手动操作或源(NTP、PTP)同步的结果,系统时钟可以(并且将在实践中!)在外部进行调整。

【讨论】:

哎呀,是的,你是对的,我很抱歉,但我将编辑我的问题更具体。我更感兴趣的是时间的内部表示如何与挂钟时间相关。 @user513951 随着您的最新更新,它有点变成了 XY 问题。你怎么知道时钟不会在一两个小时内改变?无论如何,当 stable_clock 是专门围绕它设计的时候,你为什么要致力于 system_clock?不过,DST 更改本身不会更改刻度数。 是的,这里有一个 XY 问题,因为几乎可以肯定有另一种解决方案来解决“可以将在不同机器上标记的对象发送到同一台机器并按其创建时间排序原来的电脑。”由于排序的准确性只在 +/- 5 秒内很重要,在我看来,只要许多机器或多或少地使用 NTP 同步,相对于 UNIX 纪元的 uint 时间戳就应该足够好了 -- 除非 uint 时间戳由于 DST 之类的原因而跳来跳去。 @user513951 我认为,您的最新更新可以更好地定义问题,我相信您可以通过该描述获得更好的答案,而不是通用的。预计时间戳不会在 DST 上跳跃。但是,NTP 是一种原始的同步方式,我已经看到我们网络中的时钟相差超过一秒,除非机器在 PTP 上。 我确实从这个问题中获得了足够的信息来满足我对基本细节的好奇心,所以我将把它留在原处,但根据您的建议 I've created a new question。谢谢!

以上是关于std::chrono::system_clock.now().time_since_epoch().count() 的值是不是单调增加?的主要内容,如果未能解决你的问题,请参考以下文章

如何找到纪元时间戳和 std::chrono::system_clock::now 之间的时间差(以毫秒为单位)

std::chrono::system_clock.now().time_since_epoch().count() 的值是不是单调增加?

C++中时间转换

如何使用 std::chrono 库设置特定时间?

当前本地时间高精度

c++11测试时间封装