问题描述
我正在摆弄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_clock
和utc_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下载并手动将其复制到位。