You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSVC2022+Windows11下用std::chrono获取America/Montreal时区遇异常

解决方案:封装安全的时区信息获取函数

首先要明确:locate_zone返回非空指针只能说明该时区在数据库中存在,但不代表调用get_info时不会因为ICU数据或MSVC实现的问题抛出异常——这也是你当前空判断无效的原因。

目前MSVC的std::chrono时区模块没有提供直接的预检查API来判断某个时间点是否能安全获取时区信息,最务实的方案是把try/catch封装成一个工具函数,对外提供类似预检查的接口:

#include <chrono>
#include <optional>

std::optional<std::chrono::sys_info> safe_get_timezone_info(const std::chrono::time_zone* zone, std::chrono::sys_days date)
{
    if (!zone)
        return std::nullopt;
    try
    {
        return zone->get_info(date);
    }
    catch (...)
    {
        // 捕获所有时区相关异常,返回空值表示获取失败
        return std::nullopt;
    }
}

然后修改你的测试代码,用这个函数替代直接调用get_info,就能用if判断结果是否有效:

#include <chrono>
#include <optional>

// 上面的safe_get_timezone_info函数放在这里

int main(int, char**)
{
    using namespace std::chrono;
    auto z = get_tzdb().locate_zone("America/Montreal");
    
    auto QuebecDay = 2023y / 6 / 24;
    auto info_opt = safe_get_timezone_info(z, sys_days(QuebecDay));
    
    if (info_opt)
    {
        // 成功获取时区信息,使用info_opt.value()访问
        auto info = *info_opt;
        // 后续逻辑...
    }
    else
    {
        // 处理获取失败的情况
    }
    return 0;
}

额外说明

  • 你使用的ICU版本仍存在该问题,说明这可能是MSVC对ICU数据的适配bug,而非ICU本身的问题。可以尝试更新到最新的MSVC 2022版本(比如17.8及以上),微软可能在后续补丁中修复这类特定时区的异常问题。
  • 如果需要批量预检查多个时区或时间点,可以在程序启动时提前调用safe_get_timezone_info做一次预校验,把可用的时区/时间点缓存起来,避免运行时重复捕获异常。

内容的提问来源于stack exchange,提问作者Daniel Anderson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:22:18