两个日期之间的秒数,包括闰秒
Number of seconds between two dates including leap seconds
我正在研究 C++ 中的时间表示。
我想要一个严格单调的时间表示,它可以很好地处理闰秒。 C++20 中的 utc_clock
应该可以做到这一点,由于我的编译器还不支持这个版本,所以我使用 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
的解析问题,我也试过在clock_cast<utc_clock>
之前做time_point_cast<seconds>(...)
,但结果没有改变。
我也尝试过使用 2017-01-02 作为第二个日期,以防 2016-12-31 23:59:60 和 2017-01-01 00:00 之间出现问题 - 飞跃第二个也没有出现
您似乎正在使用 OS 提供的时区数据库 (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-supplied,但格式略有不同。任何一个文件都可以,因为它们中有重复的信息。 tz.cpp 将搜索两者。如果您的平台未提供这些文件中的任何一个,您可以从 the IANA data download 下载并手动将其复制到位。
我正在研究 C++ 中的时间表示。
我想要一个严格单调的时间表示,它可以很好地处理闰秒。 C++20 中的 utc_clock
应该可以做到这一点,由于我的编译器还不支持这个版本,所以我使用 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
的解析问题,我也试过在clock_cast<utc_clock>
之前做time_point_cast<seconds>(...)
,但结果没有改变。
我也尝试过使用 2017-01-02 作为第二个日期,以防 2016-12-31 23:59:60 和 2017-01-01 00:00 之间出现问题 - 飞跃第二个也没有出现
您似乎正在使用 OS 提供的时区数据库 (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-supplied,但格式略有不同。任何一个文件都可以,因为它们中有重复的信息。 tz.cpp 将搜索两者。如果您的平台未提供这些文件中的任何一个,您可以从 the IANA data download 下载并手动将其复制到位。