如何安全地clock_cast天?

我正在使用HowardHinnant/date来代替 Clang/GCC 中尚不可用的新 C++20 日历/时区设施。我的问题同样适用于两种实现:我如何安全地clock_cast time_point拥有days持续时间?

当我尝试:

using namespace date; // or using std::chrono in C++20
tai_time<days> tai{days{42}};
sys_days sys = clock_cast<std::chrono::system_clock>(tai);

我收到最后一条语句的“无可行转换”错误。事实证明,结果使用的持续时间为common_type<days, seconds>,该持续时间来自utc_clock::to_sys()转换中使用的持续时间。常见的持续时间类型是std::chrono::seconds,所以不能直接转换为days持续时间是正常的。

如果我使用显式,我可以让它编译duration_cast

using namespace date; // or using std::chrono in C++20
tai_time<days> tai{days{42}};
auto casted = clock_cast<std::chrono::system_clock>(tai);
sys_days sys{std::chrono::duration_cast<days>(casted.time_since_epoch())};

...但我担心由于截断(特别是对于纪元之前的日期),结果可能会延迟一天。这是做我想做的事情的正确方法吗?我应该使用floor而不是duration_cast吗?

为什么还有一个std::common_type_t<Duration, std::chrono::seconds>inutc_clock::to_sys()呢?它不应该简单地返回相同的持续时间类型吗?

回答

该原因clock_cast坚持至少seconds精度是因为历元之间的偏移system_clocktai_clock具有的精度seconds

auto diff = sys_days{} - clock_cast<system_clock>(tai_time<days>{});
cout << diff << " == " << duration<double, days::period>{diff} << 'n';

输出:

378691210s == 4383.000116d

所以一个days精确的演员会是有损的。这是另一种看待它的方式:

cout << clock_cast<tai_clock>(sys_days{2021_y/June/1}) << 'n';

输出:

2021-06-01 00:00:37

即TAI 目前system_clock在日历方面领先 37 秒。

如果您只想要日期,我建议round<days>(result)

cout << round<days>(clock_cast<tai_clock>(sys_days{2021_y/June/1})) << 'n';

输出:

2021-06-01 00:00:00

可以想象floor在一个方向和另一个方向使用ceil,但这将非常容易出错。 round会很好,因为从整数天数的偏移量目前只有 37 秒并且增长非常缓慢。


以上是如何安全地clock_cast天?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>