You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将UTC Unix时间戳转换为无时区/夏令时变更的原分解时间?

解决UTC Unix时间戳还原为原始分解时间的问题

你遇到的核心问题是用错了解析函数——localtime()是专门把Unix时间戳转换成本地时区的分解时间的,而你需要的是还原出UTC时区的原始时间,这时候应该用gmtime()函数!

Unix时间戳本身就是基于UTC的,所以用gmtime()来解析它,得到的struct tm会直接对应UTC时间,完全不会受到本地时区或夏令时的影响,正好匹配你用_mkgmtime()生成时间戳时的原始输入。

修改后的测试代码

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>

int main() {
    struct tm info;
    char buffer[80];

    info.tm_year = 2022 - 1900;
    info.tm_mon = 5 - 1;
    info.tm_mday = 19;
    info.tm_hour = 15;
    info.tm_min = 3;
    info.tm_sec = 0;
    info.tm_isdst = 0;

    uint32_t time_passed_utc = _mkgmtime(&info);
    printf("time_passed_utc uint32: %lu\n", time_passed_utc); 
    // 输出:1652972580

    strftime(buffer, sizeof(buffer), "time_passed_utc-> %c", &info );
    printf("%s\n", buffer); 
    // 输出:05/19/22 15:03:00

    printf("\n\n");

    time_t rawtime = 1652972580;
    struct tm ts;
    char buf[80];

    // 改用gmtime()解析UTC时间戳
    ts = *gmtime(&rawtime);
    // 这里不需要手动设置tm_isdst,因为gmtime返回的UTC时间不会涉及DST
    strftime(buf, sizeof(buf), "%a %Y-%m-%d %H:%M:%S UTC", &ts);
    printf("%s\n", buf); 
    // 现在输出正确结果:Thu 2022-05-19 15:03:00 UTC

    // 如果需要完全匹配原始的简洁格式,也可以这样:
    strftime(buf, sizeof(buf), "%m/%d/%y %H:%M:%S", &ts);
    printf("还原后的原始格式:%s\n", buf);
    // 输出:05/19/22 15:03:00

    return(0);
}

关键说明

  • gmtime():和localtime()相对,它将Unix时间戳转换为UTC时区struct tm结构,完全忽略本地时区设置,这正是你需要的还原逻辑。
  • 关于线程安全:如果你的代码是多线程环境,建议使用线程安全版本——Windows下用gmtime_s(),POSIX系统用gmtime_r(),避免因共享内部缓冲区导致的线程问题。
  • 为什么localtime()不行?因为它会自动把UTC时间戳转换为你当前系统的本地时区(比如你示例里的东欧时区,UTC+3,所以15:03变成了18:03),这和你的需求完全相悖。

这样修改后,就能精准还原出你最初输入的分解时间,不会有任何时区或夏令时的偏移啦!

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

火山引擎 最新活动