为何mktime()返回值为0?C语言时间转换问题排查
mktime()返回0的问题排查
问题描述
我编写了如下C语言代码,用于将指定日期时间转换为epoch时间戳:
time_t test(void) { int year = 2025, month = 5, day = 11, hour = 16, minute = 32, second = 9; struct tm t = {0}; t.tm_year = year - 1900; t.tm_mon = month - 1; t.tm_mday = day; t.tm_hour = hour; t.tm_min = minute; t.tm_sec = second; t.tm_isdst = -1; logprintf("Before mktime: tm_year=%d, tm_mon=%d, tm_mday=%d, tm_hour=%d, tm_min=%d, tm_sec=%d, tm_isdst=%d\n", t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, t.tm_isdst); logprintf("%d: expiration time of cert in YY-MM-DD format: %d-%d-%d %d:%d:%02d\n", __LINE__, year, month, day, hour, minute, second); time_t res = mktime(&t); logprintf("%d: expiration time of cert in epoch time %ld\n", __LINE__, res); return res; // Convert to epoch time (local timezone) } int main(void) { test(); return 0; }
运行代码后得到如下输出:
# ./test Before mktime: tm_year=125, tm_mon=4, tm_mday=11, tm_hour=16, tm_min=32, tm_sec=9, tm_isdst=-1 4986: expiration time of cert in YY-MM-DD format: 2025-5-11 16:32:09 4989: expiration time of cert in epoch time 0
但mktime()返回值为0,请问我在代码实现中遗漏了什么?
问题原因与解决方法
首先要明确:mktime()转换失败时返回的是(time_t)-1,你看到的0是打印格式错误导致的——time_t在多数64位系统中是64位整数,用%ld(32位长整数格式)打印会截断(time_t)-1,最终显示为0。
针对问题的排查和修复步骤:
1. 修正打印格式,确认真实返回值
把打印time_t的代码改成:
logprintf("%d: expiration time of cert in epoch time %lld\n", __LINE__, (long long)res);
用%lld配合强制类型转换,能准确显示(time_t)-1,确认是转换失败而非真的返回0。
2. 检查时区配置
mktime()依赖本地时区进行转换,如果系统时区未正确设置(比如未配置TZ环境变量、时区数据库损坏),会导致无法解析指定时间。
可以在程序开头显式设置时区验证:
#include <stdlib.h> #include <time.h> // 在main函数或test函数开头添加 setenv("TZ", "UTC", 1); tzset();
强制使用UTC时区转换,若此时返回正常,说明是时区配置问题。
3. 确保struct tm字段的完整性
虽然你用struct tm t = {0}做了清零,但某些系统的struct tm包含tm_wday(星期几)、tm_yday(年内第几天)等字段,虽然mktime()理论上会自动计算这些值,但在部分环境中,显式初始化这些字段为0可能解决问题:
struct tm t = {0}; // 原有赋值不变 t.tm_wday = 0; t.tm_yday = 0;
4. 验证时间合法性
你指定的2025-05-11 16:32:09是合法时间,但可以尝试转换一个更近的已知时间(比如当前时间),验证mktime()是否能正常工作,排除系统函数本身的问题。
内容的提问来源于stack exchange,提问作者MOHAMED
相关产品推荐
相关产品推荐

