c++ - 我如何将 system_clock::now() 与 c++20 中的本地时间进行比较?

标签 c++ datetime c++20

我正在测试如下的库:

std::chrono::system_clock::time_point FromDateTime(const DateTime& dateTime)
{
    std::tm tm{};
    tm.tm_year = dateTime.Year - 1900;
    tm.tm_mon = dateTime.Month - 1;
    tm.tm_mday = dateTime.Day;
    tm.tm_hour = dateTime.Hour;
    tm.tm_min = dateTime.Minute;
    tm.tm_sec = dateTime.Second;

    const auto& time = std::mktime(&tm);
    const auto& timePoint = std::chrono::system_clock::from_time_t(time);

    return timePoint;
}

TEST_F(MyLibraryFixture, GetDateTime)
{
    // Arrange
    const auto& now = std::chrono::system_clock::now();

    // Act
    const auto& actual = _testee->GetDateTime();

    // Assert
    const auto& timeDiscrepanceInSec = std::chrono::duration_cast<std::chrono::seconds>(FromDateTime(actual) - now);
    ASSERT_TRUE(timeDiscrepanceInSec.count() < 10);
}

DateTime 类型只是一个带有上述字段的原始结构。呼唤

_testee->GetDateTime();

返回一个 DateTime 结构,日期时间实际上是本地时间。由于我正在测试的库的某些固有原因,我需要将本地时间现在 的时间进行比较。我上面的代码似乎工作正常,我“希望”当我们回到夏令时它仍然可以工作。

现在,c++20 公开了许多日期时间实用程序。我浏览了文档,尝试了一些东西,但无法找到与上述代码片段相对应的可靠版本。有没有可能(我的意思是,不使用 std::mktime 和奇怪的 std::tm)?

我最接近的是这个,但它仍然是错误的(我有一个小时的差异):

std::chrono::time_point<std::chrono::local_t, std::chrono::seconds> FromDateTime(const DateTime& dateTime)
{
    const auto& d = std::chrono::year_month_day(std::chrono::year(dateTime.Year), std::chrono::month(dateTime.Month), std::chrono::day(dateTime.Day));
    const auto& t = std::chrono::hours(dateTime.Hour) + std::chrono::minutes(dateTime.Minute) + std::chrono::seconds(dateTime.Second);
    const auto& dt = std::chrono::local_days(d) + t;

    return dt;
}

TEST_F(MyLibraryFixture, GetDateTime)
{
    // Arrange
    const auto& now = std::chrono::utc_clock::now();

    // Act
    const auto& actual = _testee->GetDateTime();

    // Assert
    const auto& timeDiscrepanceInSec = std::chrono::duration_cast<std::chrono::seconds>(FromDateTime(actual).time_since_epoch() - now.time_since_epoch());
    ASSERT_TRUE(timeDiscrepanceInSec.count() < 10);
}

最佳答案

这是与您的第一个版本 FromDateTime 等效的 C++20 代码:

std::chrono::system_clock::time_point
FromDateTime(const DateTime& dateTime)
{
    using namespace std::chrono;
    auto local_tp = local_days{year{dateTime.Year}/dateTime.Month/dateTime.Day} +
        hours{dateTime.Hour} + minutes{dateTime.Minute} + seconds{dateTime.Second};
    zoned_time zt{current_zone(), local_tp};
    return zt.get_sys_time();
}

您在创建 local_time 方面走在了正确的轨道上使用 local_days .

无需明确命名 year_month_day类型。这是使用 / 为您生成的符号。

一旦你有了本地时间,你就可以通过构建一个zoned_time将它与你计算机的本地时区相关联。与 current_zone()local_time .

然后你可以提取sys_time来自 zoned_time . sys_timetime_point<system_clock, seconds> (秒精度 system_clock::time_point ),这是 UTC(不包括闰秒)。这隐式转换为返回类型:system_clock::time_point .

如果需要,您可以解释 local_time关于其他时区,而不是您计算机的本地时区。例如:

    zoned_time zt{"America/New_York", local_tp};

一般来说,zoned_time是一种方便的类型,用于在 local_time 之间进行翻译和 sys_time .

关于c++ - 我如何将 system_clock::now() 与 c++20 中的本地时间进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70784886/

相关文章:

c++ - malloc() : memory corruption (fast) c++

c++ - 在没有显示的情况下使用 GTK

c++ - 如何在 WinDbg 执行期间打印每个函数调用?

.net - DateTime.Parse 在 XP 和 Windows 7/8 上不同

java - 为什么我的日期无法解析

c++ - 固定大小的 std::span 与 std::array

Python Packing int32 但不起作用?

python - 将日期函数应用于列以提取日期属性

c++ - 不能在 C++20 中将 std::cin 与 char* 或 char[] 一起使用

c++ - C++20 是否为 "overflow"的有符号整数很好地定义了左移?