如何比较ISO 8601格式的UTC时间字符串并判断时间先后
跨平台ISO 8601时间字符串比较方案
方案1:直接字符串比较(限定场景适用)
如果两个待比较的ISO 8601字符串时区偏移完全一致(如你示例中均为+01:00),可以直接用普通字符串比较函数得到正确结果,ISO 8601格式默认按年/月/日/时/分/秒顺序排列,字符排序和时间先后顺序完全对应。
仅适用于两个字符串时区偏移相同的场景,时区不同时会得到错误结果
代码示例(C语言):
// 返回值小于0说明s1更早,等于0说明时间相同,大于0说明s1更晚 int cmp_iso8601_same_tz(const char* s1, const char* s2) { return strcmp(s1, s2); }
方案2:解析为时间戳后比较(全场景通用,跨Windows/Linux)
不受时区差异影响,双系统兼容,是通用解决方案。
实现逻辑
- Linux环境直接用原生
strptime解析日期时间部分,Windows环境轻量实现适配ISO 8601的解析函数 - 手动解析时区偏移部分,转换为秒级偏移量调整时间
- 统一转换为UTC时间戳后直接比较大小
完整可运行代码
#include <stdio.h> #include <time.h> #include <string.h> #ifdef _WIN32 // Windows下补全ISO 8601专用strptime实现 char* strptime(const char* s, const char* f, struct tm* tm) { memset(tm, 0, sizeof(struct tm)); int y, M, d, h, m, sec; if (sscanf(s, "%d-%d-%dT%d:%d:%d", &y, &M, &d, &h, &m, &sec) == 6) { tm->tm_year = y - 1900; tm->tm_mon = M - 1; tm->tm_mday = d; tm->tm_hour = h; tm->tm_min = m; tm->tm_sec = sec; return (char*)(s + 19); // 跳过固定长度的"YYYY-MM-DDTHH:MM:SS"部分 } return NULL; } #endif time_t iso8601_to_timestamp(const char* iso_str) { struct tm tm_time = {0}; char* tz_ptr = strptime(iso_str, "%Y-%m-%dT%H:%M:%S", &tm_time); if (tz_ptr == NULL) return (time_t)-1; // 解析时区偏移 int tz_offset = 0; if (*tz_ptr == '+' || *tz_ptr == '-') { int tz_h, tz_m; if (sscanf(tz_ptr, "%d:%d", &tz_h, &tz_m) == 2) { tz_offset = tz_h * 3600 + tz_m * 60; if (*tz_ptr == '+') tz_offset = -tz_offset; // 转换为UTC需要减去正偏移 } } else if (*tz_ptr == 'Z') { // 匹配UTC零时区标识 tz_offset = 0; } // 转换为UTC标准时间戳 time_t local_ts = mktime(&tm_time); if (local_ts == (time_t)-1) return (time_t)-1; return local_ts + tz_offset - timezone; // 修正系统时区差异 } // 比较函数:返回1说明s1更晚,返回-1说明s2更晚,返回0说明时间相同,返回-2说明解析错误 int compare_iso8601(const char* s1, const char* s2) { time_t t1 = iso8601_to_timestamp(s1); time_t t2 = iso8601_to_timestamp(s2); if (t1 == (time_t)-1 || t2 == (time_t)-1) return -2; if (t1 > t2) return 1; if (t1 < t2) return -1; return 0; } // 测试用例 int main() { const char* string1 = "1997-07-16T19:20:30+01:00"; const char* string2 = "2000-07-17T20:20:30+01:00"; int res = compare_iso8601(string1, string2); if (res > 0) { printf("string1更晚\n"); } else if (res < 0) { printf("string2更晚\n"); } else { printf("两个时间相同\n"); } return 0; }
注意事项
- 代码同时兼容带
Z后缀的UTC时间和带正负时区偏移的ISO 8601格式 - 解析得到的时间戳为UTC标准时间戳,比较结果不受运行设备的本地时区影响
内容的提问来源于stack exchange,提问作者Mirror_Boy047
相关产品推荐
相关产品推荐

