std::format 不支持 locale 本地化日期输出,%Y、%B、%x 等始终按 C locale 解析,std::locale 参数被静默丢弃;真本地化须用 std::put_time + std::ostringstream 配合 std::time_put facet。
std::format 不能靠 locale 实现中文/德文等本地化日期输出,所有 {:%Y}、{:%B}、{:%x} 都按 C locale 固定解析,传入的 std::locale 参数会被静默丢弃——这不是 bug,是 C++20 标准行为。
std::format("{:%Y年%m月%d日}", tp) 看似能用,实则危险
它输出 “2026年04月30日” 是因为 “年”“月”“日” 是 UTF-8 字面量,被原样拼接;而 %Y 和 %m 仍走 C locale(永远是 “2026”“04”,不是 “二〇二六”“四”)。真正本地化需要月份名翻译、日期顺序切换(如德语 %d.%m.%Y),std::format 完全不查 std::time_put facet,也不支持 {:L} 扩展。
编译能过只是侥幸:格式串里混中文不报错,但属于硬编码,和 locale 无关
跨平台风险高:Windows 上
极可能构造失败,而
中的
会被直接丢弃
在任意 locale 下都输出美式
,不会变成中文
或德文
std::format 只接受 zoned_time 或 sys_time,不认 time_t 和 tm*
直接传
或
会编译失败,报错类似
。C++20 日历与时钟类型才是唯一合法输入源。
正确路径:
→
→ (可选)
想输出本地时间?必须经
中转,不能靠
后再塞进
UTC 时间最稳:
+
带时区输出必须用 zoned_time,%Z 和 %z 仅对其有效
输出时区缩写(如
),
输出 UTC 偏移(如
),但这两个说明符对
或
使用时会被静默忽略——只在
上有意义。
C函数速查手册(CHM版)
C函数速查手册(CHM版)
下载
立即学习
“
C++免费学习笔记(深入)
”;
先确认时区存在:
遍历,别直接
,否则可能抛
安全链路示例:
→
若需偏移而非缩写,用
;但注意它输出的是
,不是
(后者需手动拆解拼接)
真要本地化?切回 std::put_time + std::ostringstream
不走 locale 路线,唯一合规路径是传统流机制:
激活 facet,靠
驱动
实现翻译与顺序适配。
关键三步:
→
→
注意转换:
必须先过
,再
;不能直接传
Linux/macOS 通常预装完整 locale 数据;Windows 需确认系统是否启用对应语言,且
或
兼容性更稳
最容易被忽略的一点:你写的每个中文字符(“年”“月”“日”)都是硬编码字面量,和 locale 无关;而真正的本地化字段(如月份名、星期名、日期顺序)必须由
在运行时查表生成——这一步
永远跳过。
zh_CN.UTF-8std::format(loc, )loc%x05/10/2626/05/1010.05.26std::time_tstruct tm*no matching function for call to 'format'std::chrono::system_clock::from_time_t(t)sys_timezoned_time{zone, tp}zoned_timestd::localtime()std::formatstd::chrono::utc_clock::now()std::format("{:%Y-%m-%d %H:%M:%S}Z", utc_now)%ZCST%z+0800sys_timeutc_timezoned_timestd::chrono::get_tzdb().zoneslocate_zone("Asia/Shanghai")std::runtime_errorauto zt = std::chrono::zoned_time{std::chrono::current_zone(), std::chrono::system_clock::now()};std::format("{:%Y-%m-%d %H:%M:%S %Z}", zt)%z+0800+08:00std::formatimbue()std::put_timestd::time_put::put()std::locale loc{"zh_CN.UTF-8"}oss.imbue(loc)oss std::chrono::system_clock::time_pointstd::chrono::system_clock::to_time_t()std::localtime()tp"Chinese_China.936""zh-CN"std::time_putstd::format