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

如何比较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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:15:00