【问题标题】:What does time_since_epoch() actually represent in a std::chrono::local_time?time_since_epoch() 在 std::chrono::local_time 中实际代表什么?
【发布时间】:2021-08-22 00:55:10
【问题描述】:

我想通过发送time_since_epoch().count() 值来序列化std::chrono::local_time。我的问题是非 C++ 接收器应该如何解释该值?它是自当地时间午夜 (1970-01-01T00:00:00) 纪元以来的实际滴答数?夏令时的变化呢? time_since_epoch() 是挂钟时间的双射吗?也就是说,std::chrono::local_time::time_since_spoch() 的两个值是否可以代表相同的挂钟/日历时间?

我在通常的地方找不到有关std::chrono::local_time::time_since_spoch() 解释的详细信息:cppreference、最新的 C++ 标准草案或 Howard Hinnant 的 date library documentation

'为什么还要序列化std::chrono::local_time?',你可能会问。好吧,一个用例将是一个楼宇自动化系统,它必须在特定日期的给定本地时间执行特定任务,而不管时区或夏令时如何。例如,“在 2021 年世界地球日(4 月 22 日)当地时间 20:00 关灯。

编辑: “你可能会问,为什么不将其序列化为 ISO8601 日期/时间(没有任何偏移)?”。我想使用二进制协议(例如 CBOR)将其序列化为紧凑数字。

【问题讨论】:

  • 我目前正在使用 Howard Hinnant 的日期库来代替尚未准备好的 C++20 标准库实现。它们的 API 几乎相同。
  • 历元通常是 1970-01-01T00:00:00 UTC,而不是本地午夜。这意味着它代表了一个确切的时间瞬间,而与任何人类表示无关。这意味着您不必考虑时区或夏令时或闰秒或任何事情
  • @MooingDuck 我的意思是chrono::local_t pseudclock 使用的“纪元”。不是实际的 Unix 纪元。其他时钟(chrono::tai_clockchrono::gps_clock)的纪元与 Unix 纪元不同。
  • @MooingDuck:“std::chrono::local_time 没有时钟就无法解释”。它的意思是在没有任何特定时区的本地上下文中解释(因此得名)。将我的用例解释为:“我希望该建筑物在地球日 20:00 使用建筑物的当地时间(当建筑物所在地变暗时)关闭其灯光”。与自动化服务器交互的客户端将了解它与建筑物的本地时间相关。另请参阅howardhinnant.github.io/date/tz.html#loc_vs_sys中的“除夕派对”说明
  • @MooingDuck:local_time 也使用std::chrono::local_t 伪时钟。 local_time 被简单地定义为template <class Duration> using local_time = std::chrono_point<std::chrono::local_t, Duration>。要将 local_time 转换为特定的通用时间点(例如,UTC),您必须包含 time_zone 或与 UTC 的偏移量。

标签: c++ time c++20 chrono localtime


【解决方案1】:

local_time 中的值与sys_time 中的值完全相同。例如:

auto lt = local_days{June/3/2021} + 18h + 30min;

lt 是具有指示值的本地时间。只需将其更改为sys_time 就是将local_days 更改为sys_days

auto st = sys_days{June/3/2021} + 18h + 30min;

即现在可以断言st.time_since_epoch() == lt.time_since_epoch()ltst 之间的唯一区别是语义。

因此,您可以告诉客户使用这个数字,就好像它是 Unix Time,然后它可以导出年、月、日、时间信息,然后将该信息视为本地时间(大概) 他们的本地时区。

在进行“重新解释演员表”时,很可能本地指示时间可能不存在,或者可能因为其中有两个而模棱两可。通过避免一天中的 00:00:00 - 04:00:00 范围内的时间,可以提高不遇到这种情况的几率。如果确实遇到这种情况,那么对于如何处理它没有一个正确的答案。您只需在其余文档中说明一项政策。

...

或者他们只是用 C++20 编写解析器... :-)

【讨论】:

  • 我认为这只有在local_time 来自std::chrono::utc_clock 时才是正确的,而std::chrono::steady_clock 几乎肯定是错误的,不是吗?
  • 不。 steady_clock 不是此对话的一部分。它不存在于日历和当地时间的世界中。
  • 我不相信它真的能避免任何问题。总数只是day_count * ticks_per_day + day_tick_count。或者您可以使用% 进行反向计算。这两种表示可以表示完全相同的事物,而不会丢失信息,也不会在处理本地时间时丢失问题。 :-)
  • 啊,是的,这源于local_days 的属性总是有 86400 秒,因为日历数学的设计与sys_time 相同。我可能说得不准确,但至少我现在很清楚。
  • 对于自动化控制器来说,最好的办法可能是在客户端通过日期 + 时间时计算 UTC 时间,拒绝不存在的时间并要求客户端选择不明确的时间。此后,它始终交换为 UTC。一个复杂的问题是,如果在对时间表进行编程后将自动化控制器设置为不同的时区。无论如何,你给了我很好的指导,让我弄清楚其余的事情。我不想占用你更多的时间。谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-12-08
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-05
  • 2010-09-24
相关资源
最近更新 更多