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

为何strptime()无法解析yyyymmddhhmmss格式无分隔符日期时间字符串?

问题分析与解决

你遇到的问题核心是AIX 5.3系统的strptime()实现不支持连续无分隔符的格式说明符,比如%Y%m%d%H%M%S这种写法无法被正确解析,导致strptime()返回NULL,此时struct tm结构的内容未被正确初始化,后续mktime()处理无效的时间结构就会返回-1(转换成unsigned long后就是4294967295),对应输出1970年的初始时间。

另外你代码里没有检查strptime()的返回值,这也是一个容易忽略的点——一旦解析失败,后续的时间处理都是无效的。

解决方法

方法1:用sscanf()直接解析固定长度字段

sscanf()可以精准匹配固定长度的数字段,刚好适合这种无分隔符的时间格式,代码修改如下:

#include <stdio.h>
#include <time.h>
#include <string.h>

int main(int argc, char *argv[])
{
    struct tm stm;
    time_t utm;
    char strtime[] = "20221116082310"; // yyyymmddhhmmss
    int year, mon, day, hour, min, sec;

    // 用sscanf拆分固定长度的字段
    if (sscanf(strtime, "%4d%2d%2d%2d%2d%2d", &year, &mon, &day, &hour, &min, &sec) == 6) {
        memset(&stm, 0, sizeof(stm));
        stm.tm_year = year - 1900; // tm_year是从1900年开始的偏移量
        stm.tm_mon = mon - 1;      // tm_mon范围是0-11(对应1-12月)
        stm.tm_mday = day;
        stm.tm_hour = hour;
        stm.tm_min = min;
        stm.tm_sec = sec;

        // 设置时区为意大利时区(CET/CEST)
        setenv("TZ", "CET-1CEST,M3.5.0/2,M10.5.0/3", 1);
        tzset();

        utm = mktime(&stm);
        if (utm != -1) {
            printf("%lu %s\n", (unsigned long)utm, ctime(&utm));
        } else {
            printf("时间转换失败\n");
        }
    } else {
        printf("字符串解析失败\n");
    }

    return 0;
}

方法2:手动拼接带分隔符的字符串再用strptime()解析

如果一定要用strptime(),可以把无分隔符字符串转换成带分隔符的格式,比如"2022-11-16 08:23:10",再用标准格式解析:

#include <stdio.h>
#include <time.h>
#include <string.h>

int main(int argc, char *argv[])
{
    struct tm stm;
    time_t utm;
    char strtime[] = "20221116082310";
    char formatted[20];

    // 拼接成带分隔符的字符串
    snprintf(formatted, sizeof(formatted), "%.*s-%.*s-%.*s %.*s:%.*s:%.*s",
             4, strtime, 2, strtime+4, 2, strtime+6,
             2, strtime+8, 2, strtime+10, 2, strtime+12);

    memset(&stm, 0, sizeof(stm));
    // 设置时区
    setenv("TZ", "CET-1CEST,M3.5.0/2,M10.5.0/3", 1);
    tzset();

    if (strptime(formatted, "%Y-%m-%d %H:%M:%S", &stm) != NULL) {
        utm = mktime(&stm);
        printf("%lu %s\n", (unsigned long)utm, ctime(&utm));
    } else {
        printf("解析失败\n");
    }

    return 0;
}

关键注意点

  • AIX系统的strptime()对格式的兼容性较差,老旧版本(比如5.3)不支持连续无分隔符的格式说明符,必须用分隔符分隔各个时间字段。
  • struct tm的字段有特殊要求:tm_year是年份减1900,tm_mon是月份减1(0代表1月),手动填充时必须注意。
  • 要正确输出意大利时区的时间,需要通过setenv("TZ", ...)设置时区并调用tzset()生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 19:50:25