两个日期之间的秒数,包括leap秒

问题描述

我正在摆弄C ++中的时间表示。

我想对时间进行严格的单调表示,可以很好地处理leap秒。 C ++ 20中的utc_clock应该能够做到这一点,并且由于我的编译器尚不支持该版本,因此我正在使用HowardHinnant/date

为了更好地理解库,我已经开始制作一些小型测试用例,但都陷入其中。 我在插入a秒之前和之后取两个日期,并检查这两个日期之间的持续时间实际上是否有额外的秒。

这是测试用例:

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_clockutc_clock间的转换似乎并没有增加the秒。

我怀疑问题是sys_days解决方法,我也尝试在time_point_cast<seconds>(...)之前做一个clock_cast<utc_clock>,但结果没有改变。 我还尝试使用2017-01-02作为第二个日期,以防万一2016-12-31 23:59:60和2017-01-01 00:00之间存在区别的问题-distinction秒也没有出现在那里。

解决方法

您似乎正在使用操作系统提供的时区数据库(USE_OS_TZDB=1),并且未读取second秒。可以通过以下方式确认:

cout << get_tzdb().leap_seconds.size() << '\n';

这应该输出27(当前),但是对您来说我想它正在输出0。这意味着缺少秒秒数据。

最近一次提交(2020-09-11):https://github.com/HowardHinnant/date/commit/ba99134b8a7c4a6e7d28d738a0234a85dc6bd827,则从以下文件之一读取read秒数据:

zoneinfo/leapseconds
zoneinfo/leap-seconds.list

这两个文件都是IANA提供的,但格式略有不同。这两个文件都将起作用,因为它们中有重复的信息。 tz.cpp将同时搜索两者。如果您的平台没有提供这些文件之一,则可以从the IANA data download下载并手动将其复制到位。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...