如何使用 std::chrono + MSVC 2022 + Windows 11 获取美国/蒙特利尔时区

问题描述 投票:0回答:1

在 Windows 11 中使用 MSVC 2022,当我尝试使用 std::chrono 获取一些时区信息时,它失败,并在我从中提取的某些时区出现异常:

std::chrono::get_tzdb().zones

what() 函数只是返回未知错误! 我简化了代码只是为了显示问题。 我想做的是给我们一个 if 语句来检查时区是否可以使用! 现在我必须用 try/catch 来“散布”我的代码

这是失败的代码:

#include <chrono>

int main(int, char**)
{
    using namespace std::chrono;
    auto z = std::chrono::get_tzdb().locate_zone("America/Montreal");
    if (z != nullptr)   // useless
    {
        auto QuebecDay = 2023y / 6 / 24;
        auto info = z->get_info(std::chrono::sys_days(QuebecDay));
    }
    return 0;
}

我从 tzdb 枚举的许多时区都遇到同样的问题。 我的 icu.dll 日期为:2023 年 11 月 14 日,所以是最近的 我使用的是 Windows 11 Professional 23H2

c++ c++20 c++-chrono windows-11 visual-c++-2022
1个回答
0
投票

围绕

std::chrono::locate_zone
的简单包装应该为您提供您喜欢的错误检查样式:

#include <chrono>
#include <string_view>

auto
my_locate_zone(std::string_view tz)
{
    try
    {
        return std::chrono::locate_zone(tz);
    }
    catch(...)
    {
        return static_cast<std::chrono::time_zone const*>(nullptr);
    }
}

int main(int, char**)
{
    using namespace std::chrono;
    auto z = my_locate_zone("America/Montreal");
    if (z != nullptr)
    {
        auto QuebecDay = 2023y / 6 / 24;
        auto info = z->get_info(std::chrono::sys_days(QuebecDay));
    }
    return 0;
}

“America/Montreal”是位于 IANA 时区数据库“backward”文件中的“America/Toronto”的链接。可能ICU不包含这部分数据库。如果该链接包含在数据库中,

std::chrono::locate_zone
将找到它并返回指向“美国/多伦多”的指针
time_zone

© www.soinside.com 2019 - 2024. All rights reserved.