已知tm结构体的tm_mday和tm_mon,如何计算tm_yday转换Unix时间戳
基于tm_mon、tm_mday实现Unix Epoch时间计算方案
核心实现逻辑
你需要先通过月份、日期、年份手动计算出当年累计天数(即tm_yday对应的值),替换原公式中的my_tm.tm_yday*86400部分即可,步骤如下:
- 预设平年场景下,每个月月初的累计天数基准表
- 根据年份判断是否为闰年,若为闰年且月份大于2月,累计天数额外加1
- 注意适配tm结构体的字段规则:
tm_mon取值范围为0~11,0代表1月,11代表12月tm_year取值为实际年份减去1900
替换代码片段
// 计算当年累计天数yday int year = my_tm.tm_year + 1900; const int days_before_month[] = {0,31,59,90,120,151,181,212,243,273,304,334}; int yday = days_before_month[my_tm.tm_mon] + my_tm.tm_mday - 1; // 闰年判断与调整 int is_leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); if (is_leap && my_tm.tm_mon >= 2) { yday += 1; }
将原公式中的my_tm.tm_yday*86400替换为yday * 86400LL即可,添加LL后缀是为了避免整数溢出。
完整可运行修正代码
你原代码存在两个隐藏问题:一是tm_year没有减去1900适配结构体规则,二是tm_mon没有减1适配0起始的计数规则,修正后的完整代码如下:
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { char timeString[80] = {"05 07 2021 00 33 51"}; // 对应epoch毫秒值为1620347631000 struct tm my_tm = {0}; if(sscanf(timeString, "%d %d %d %d %d %d", &my_tm.tm_mon, &my_tm.tm_mday, &my_tm.tm_year, &my_tm.tm_hour, &my_tm.tm_min, &my_tm.tm_sec) != 6) { printf("sscanf failed"); return EXIT_FAILURE; } // 适配tm结构体字段规则 my_tm.tm_year -= 1900; my_tm.tm_mon -= 1; // 手动计算yday替代tm_yday字段 int year = my_tm.tm_year + 1900; const int days_before_month[] = {0,31,59,90,120,151,181,212,243,273,304,334}; int yday = days_before_month[my_tm.tm_mon] + my_tm.tm_mday - 1; int is_leap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); if (is_leap && my_tm.tm_mon >= 2) { yday += 1; } // 计算epoch时间 long long epoch_sec = my_tm.tm_sec + my_tm.tm_min*60 + my_tm.tm_hour*3600 + yday*86400LL + (my_tm.tm_year-70)*31536000LL + ((my_tm.tm_year-69)/4)*86400LL - ((my_tm.tm_year-1)/100)*86400LL + ((my_tm.tm_year+299)/400)*86400LL; long long epoch_ms = epoch_sec * 1000; printf("秒级Unix时间:%lld\n毫秒级Unix时间:%lld\n", epoch_sec, epoch_ms); return EXIT_SUCCESS; }
内容的提问来源于stack exchange,提问作者Gow.
相关产品推荐
相关产品推荐

