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

为何strptime与mktime对第三个日期生成异常时间戳?

问题:strptime与mktime转换第三个日期时结果异常

我用以下C代码从文本文件解析日期时间:

#define DATETIME_FORMAT "%Y-%m-%d %H:%M:%S"
if (!strptime(datetimestr, DATETIME_FORMAT, &record->datetime)) {
  return 0;
} else {
  record->message_size = strlen(messagestr) - 1;
  messagestr[record->message_size] = '\0';
  strcpy(record->message, messagestr);
  printf("parsed '%s' '%s' %ld\n", messagestr, datetimestr, mktime(&record->datetime));
  return 1;
}

执行后得到打印结果:

parsed 'ETC' '2023-04-03 09:00:19' 1680508819
parsed 'StandUp' '2023-04-03 09:00:47' 1680508847
parsed 'Stop' '2023-04-03 09:11:55' 1680505915

将这些时间戳转换为GMT时间后发现:

  • 1680508819 → 2023年4月3日 08:00:19
  • 1680508847 → 2023年4月3日 08:00:47
  • 1680505915 → 2023年4月3日 07:11:55

前两个时间的本地时间(09:xx)与GMT差1小时,符合夏令时的时区偏移,但第三个时间差了2小时,完全不符合预期,这是为什么?


问题原因与解决方法

核心问题是**strptime不会初始化struct tm中未被解析的字段**,包括tm_isdst(夏令时标识)。

strptime只会填充格式字符串中对应的字段(比如年、月、日、时、分、秒),而tm_isdst、tm_yday、tm_wday这些字段会保留内存里的原始垃圾值。当你调用mktime时,它会根据tm_isdst的值来判断是否应用夏令时:

  • 如果tm_isdst = -1:mktime会自动检测当前时间是否处于夏令时区间,计算正确的UTC时间戳
  • 如果tm_isdst = 0或1:mktime会强制使用非夏令时/夏令时规则,不管实际日期是否符合

你的前两次调用中,栈上的tm_isdst碰巧是-1,mktime自动检测到4月3日处于夏令时,所以计算出的时间戳对应GMT+1的本地时间(09:xx → GMT 08:xx)。但第三次调用时,tm_isdst的垃圾值是0,mktime强制按非夏令时处理,导致时区偏移变成了GMT+2(09:xx → GMT 07:xx),最终得到错误的时间戳。

解决方法很简单:在调用strptime前,手动初始化整个struct tm结构体,尤其是把tm_isdst设为-1,让mktime自动处理夏令时:

// 初始化struct tm为0,再设置tm_isdst为-1
memset(&record->datetime, 0, sizeof(struct tm));
record->datetime.tm_isdst = -1;

if (!strptime(datetimestr, DATETIME_FORMAT, &record->datetime)) {
  // ... 原有逻辑
}

这样就能保证每次mktime都自动检测夏令时,不会出现随机错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 04:10:08