time_t转struct tm用localtime(本地时区)或gmtime(utc),取决于需求;二者均非线程安全,多线程须用localtime_r或localtime_s;struct tm转time_t用mktime,需注意字段范围与初始化,不可memcpy互转。

time_t 转 struct tm 用哪个函数?localtime 还是 gmtime?
取决于你要转成本地时区还是 UTC 时间。绝大多数场景下你想要的是本地时间,直接用 localtime;如果处理日志归档、跨时区服务或与 ISO 8601 对齐,才用 gmtime。
注意:localtime 和 gmtime 返回的都是 struct tm*,指向静态内存,**不是线程安全的**。多线程里必须改用 localtime_r(POSIX)或 localtime_s(Windows),否则会出现时间错乱。
-
localtime(&t):返回本地时间,但不可重入 -
localtime_r(&t, &tm_buf):POSIX 标准,把结果写进你传入的tm_buf -
localtime_s(&tm_buf, &t):Windows 特供,参数顺序和_r版相反
struct tm 转 time_t 为什么 mktime 返回 -1?
mktime 返回 -1 表示转换失败,常见原因不是“格式错”,而是字段值越界或无效。
struct tm 的字段有隐含约束:比如 tm_mon 必须是 0–11,tm_mday 是 1–31,tm_year 是从 1900 开始的偏移量(即 2024 年要填 124)。哪怕只错一个字段,mktime 就可能归零或返回 -1。
- 务必初始化整个
tm结构体,比如用memset(&tm, 0, sizeof(tm)),避免垃圾值干扰 -
tm_isdst设为 -1 让系统自动判断夏令时,设 0 或 1 可能导致某些日期无法解析 - 某些嵌入式 libc(如 newlib)对超出范围的日期更敏感,返回 -1 前不修正字段
time_t 和 struct tm 之间能直接 memcpy 吗?
不能。二者内存布局完全不同:time_t 通常是 4 字节或 8 字节整数(秒数),而 struct tm 是至少 9 个整型字段的结构体,大小通常为 44–56 字节(含 padding),且字段顺序、对齐方式由 ABI 决定。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
直接 memcpy 不仅得不到正确时间,还可能触发未定义行为(比如读到 padding 区域的随机值)。所有转换必须走标准函数——localtime/gmtime 和 mktime 是唯一合规路径。
顺带一提:time_t 的底层类型未标准化(可能是 long、int64_t 或其他),别假设它是 long,也别用 reinterpret_cast 强转。
跨平台处理时区和夏令时要注意什么?
Windows 和 Linux 对 tm_isdst 的处理逻辑略有差异,尤其在 DST 切换边界日(比如 3 月第二个周日):
- Linux
mktime在模糊时间(如 DST 开始当天 2:00–3:00)会按“夏令时生效”处理,除非显式设tm_isdst = 0 - Windows
mktime默认倾向标准时间,除非tm_isdst == 1或系统判定为 DST 时段 - 跨平台代码里,如果需要精确控制,建议统一设
tm_isdst = -1,然后靠mktime返回值后检查tm.tm_isdst确认实际结果
真正麻烦的是时区变更——比如某国突然废除夏令时,glibc 会随 tzdata 更新自动适配,但 Windows 需要等系统补丁,旧程序可能持续出错数月。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










