c++ - 两个日期之间的秒数,包括闰秒

标签 c++ c++20 chrono

我正在摆弄 C++ 中的时间表示。
我想要一个严格单调的时间表示,可以很好地处理闰秒。 utc_clock在 C++20 中应该能够做到这一点,因为我的编译器还不支持这个版本,我正在使用 HowardHinnant/date .
为了更好地理解这个库,我开始制作小测试用例,但卡在了一个上面。
我在插入闰秒之前和之后取两个日期,并检查这两个日期之间的持续时间实际上是否有额外的秒数。
这是测试用例:

TEST(DateTime, TimeLeap)
{
  using namespace std::chrono;
  using namespace date;

  // Two dates with a leap second in between
  // https://en.wikipedia.org/wiki/Leap_second
  auto t1 = clock_cast<utc_clock>(static_cast<sys_days>(2016_y/December/31));
  auto t2 = clock_cast<utc_clock>(static_cast<sys_days>(2017_y/January/1));

  EXPECT_EQ(duration_cast<seconds>(t2 - t1).count(), 24 * 3600 + 1);
}
但它对我来说失败了:
common/tests/datetime.cpp:39: Failure
      Expected: duration_cast<seconds>(t2 - t1).count()
      Which is: 86400
To be equal to: 24 * 3600 + 1
      Which is: 86401
好像是sys_clock之间的转换和 utc_clock不添加闰秒。
怀疑是sys_days的分辨率问题,我也试过做 time_point_cast<seconds>(...)之前clock_cast<utc_clock> ,但结果没有改变。
我也尝试使用 2017-01-02 作为第二个日期,以防万一 2016-12-31 23:59:60 和 2017-01-01 00:00 之间存在区分问题——闰秒也是没有出现在那里。

最佳答案

看起来您正在使用操作系统提供的时区数据库( USE_OS_TZDB=1 ),并且没有读取闰秒。这可以通过以下方式确认:

cout << get_tzdb().leap_seconds.size() << '\n';
这应该输出 27(当前),但对你来说我想它输出 0。这意味着缺少闰秒数据。
最近 (2020-09-11) 提交:https://github.com/HowardHinnant/date/commit/ba99134b8a7c4a6e7d28d738a0234a85dc6bd827 ,从以下任一文件中读取闰秒数据:
zoneinfo/leapseconds
zoneinfo/leap-seconds.list
这两个文件均由 IANA 提供,但格式略有不同。任何一个文件都可以,因为它们中有重复的信息。 tz.cpp 将搜索两者。如果您的平台没有提供这些文件中的任何一个,您可以从 the IANA data download 下载它。并手动将其复制到位。

关于c++ - 两个日期之间的秒数,包括闰秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64622764/

相关文章:

c++ - static constexpr 指向具有多重继承的成员函数向下转型的指针

c++ - C++20 中引入的 std::views::all 是什么?

c++11 - 如何使用 std::chrono::milliseconds 作为默认参数

C++ 20 计时码表 : How to compare time_point with month_day?

c++ - 我的程序编写每十亿个组合的更有效方法?

c++ - 循环中的C++作用域锁定阻塞了另一个线程

c++ - 与 std::semi_regular 一起使用时,带有捕获的 lambda 无法编译

c++ - chrono::month 和 chrono::months 有什么区别

c# - 我们可以使用 "goto"关键字来结束线程吗?

c++ - 在内存中有一个图像文件缓冲区,创建其缩略图的最快方法是什么?