c++oding="utf-8" ?>
不能。std::get_time不支持iso 8601的可选部分(如z、时区偏移、小数秒等);推荐使用howard hinnant的date库,它完整支持iso 8601且头文件-only;c++20的std::chrono::from_stream支持有限,依赖实现;手写解析器仅适用于固定简单格式。

std::get_time 能不能直接解析 ISO 8601?
不能。标准库的 std::get_time 对格式要求严格,只支持固定分隔符和字段顺序,无法处理 ISO 8601 中常见的可选部分(如 Z、+08:00、小数秒、省略年份等)。尝试用 "%Y-%m-%dT%H:%M:%S" 解析 "2023-10-05T14:30:45.123Z" 会失败——因为小数点后三位和 Z 不匹配任何 std::get_time 格式符。
用 Howard Hinnant 的 date 库最稳妥
这是目前 C++ 生态中事实标准的 ISO 8601 解析方案,支持完整标准(含时区、亚秒、省略字段),且头文件-only、无依赖。需先安装:git clone https://github.com/HowardHinnant/date,或通过 vcpkg/conan 安装。
基本用法:
auto tp = date::parse("2023-10-05T14:30:45.123Z", std::chrono::system_clock::time_point{});
关键点:
-
date::parse返回std::chrono::system_clock::time_point,不是time_t;需用std::chrono::system_clock::to_time_t转换 - 对带偏移的时间(如
"2023-10-05T14:30:45+08:00"),它能自动识别并转换为 UTC 时间点 - 若字符串含毫秒但目标类型只有秒精度,会截断而非四舍五入
- 不抛异常,解析失败时返回
time_point::min(),务必检查
std::chrono::from_stream 在 C++20 中可用但限制多
C++20 引入了 std::chrono::from_stream,理论上支持 ISO 8601,但实际支持程度取决于标准库实现。libstdc++(GCC)至今未完全实现时区解析,MSVC 支持较好但仍有小数秒兼容性问题。
示例(仅适用于部分平台):
std::chrono::sys_seconds tp;
std::istringstream ss("2023-10-05T14:30:45Z");
ss >> std::chrono::from_stream(tp, "%FT%TZ");
常见坑:
-
%F等价于%Y-%m-%d,但某些实现不识别%F -
%T是%H:%M:%S,无法匹配带小数秒的14:30:45.123 - 时区部分(
Z或+08:00)在多数 libstdc++ 版本中仍不可靠
手写解析器只适合简单场景
如果项目不能引入第三方库,且只要处理固定格式(如仅 YYYY-MM-DDTHH:MM:SS,无时区、无小数秒),可用 std::sscanf 快速提取:
int y,m,d,H,M,S;
if (sscanf(s.c_str(), "%d-%d-%dT%d:%d:%d", &y,&m,&d,&H,&M,&S) == 6) {
// 构造 tm 结构体再转 time_t
}
但必须注意:
- 不验证日期有效性(如 2023-02-30 会被接受)
- 忽略所有非法字符(
"2023-10-05T14:30:45Z garbage"仍可能成功) - 无法处理
T被空格替代、或省略T的变体(如"2023-10-05 14:30:45") - 时区信息完全丢弃,结果默认解释为本地时间
真正要覆盖 ISO 8601 全集,手写成本远高于引入 date 库——尤其是时区规则和闰秒边界情况。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











