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

如何用C/C++/Win32 API将1904纪元秒数转换为日期时间?

1904纪元秒数转格式化时间/struct tm 的实现方法

好问题!其实C/C++标准库或者Win32 API里并没有直接提供从1904纪元秒数转换的函数,但我们可以通过计算固定纪元偏移量来轻松实现这个需求——毕竟1904年1月1日午夜(UTC)到1970年1月1日午夜(UTC)的时间差是固定值。

核心思路:计算纪元偏移量

首先我们需要确定两个纪元之间的总秒数差:
从1904到1970共66年,其中包含17个闰年(1904、1908...1968),总天数为 66*365 +17 = 24107 天,换算成秒数就是:
24107 * 24 * 3600 = 2082844800 秒

这个值就是我们需要的偏移量——把1904纪元的秒数减去这个值,就能得到标准的Unix时间戳(1970纪元秒数),之后就可以用常规函数处理了。


方法一:使用C/C++标准库

步骤:

  1. 将1904纪元秒数转换为Unix时间戳(time_t)
  2. 用localtime/gmtime转换为struct tm
  3. 用strftime格式化输出目标字符串

代码示例:

#include <ctime>
#include <cstdint>
#include <cstdio>

int main() {
    // 1904纪元到1970纪元的秒数偏移量
    const uint64_t SECONDS_1904_TO_1970 = 2082844800ULL;
    
    // 示例:1904-01-01 00:00:00 的秒数(值为0)
    uint64_t epoch1904_sec = 0;
    
    // 转换为Unix时间戳(注意处理溢出:如果epoch1904_sec < 偏移量,说明是1904之前的时间,需额外处理)
    if (epoch1904_sec < SECONDS_1904_TO_1970) {
        fprintf(stderr, "Error: Time is before 1904-01-01 UTC\n");
        return 1;
    }
    time_t unix_time = static_cast<time_t>(epoch1904_sec - SECONDS_1904_TO_1970);
    
    // 转换为本地时间的struct tm(用gmtime则得到UTC时间)
    struct tm* time_info = localtime(&unix_time);
    if (!time_info) {
        fprintf(stderr, "Error converting time\n");
        return 1;
    }
    
    // 格式化为"hh:mm:ss MM. dd, yyyy"(%H是24小时制,%I是12小时制,按需选择)
    char time_str[100];
    strftime(time_str, sizeof(time_str), "%H:%M:%S %m. %d, %Y", time_info);
    
    printf("Formatted time: %s\n", time_str);
    return 0;
}

方法二:使用Win32 API

如果是Windows平台,也可以用Win32的时间函数来处理,核心是把1904纪元秒数转换为FILETIME(Win32的时间格式,以1601年为纪元,100纳秒为单位),再转成SYSTEMTIME或直接格式化。

代码示例:

#include <windows.h>
#include <cstdint>
#include <cstdio>

int main() {
    // 1904纪元到1601纪元的100纳秒单位偏移量
    const uint64_t TICKS_1904_TO_1601 = 95620744000000000ULL;
    const uint64_t SEC_TO_TICKS = 10000000ULL; // 1秒=10^7个100纳秒
    
    // 示例:1904-01-01 00:00:00 的秒数
    uint64_t epoch1904_sec = 0;
    
    // 转换为FILETIME的100纳秒计数
    uint64_t filetime_ticks = TICKS_1904_TO_1601 + (epoch1904_sec * SEC_TO_TICKS);
    
    FILETIME ft;
    ft.dwLowDateTime = static_cast<DWORD>(filetime_ticks & 0xFFFFFFFF);
    ft.dwHighDateTime = static_cast<DWORD>(filetime_ticks >> 32);
    
    // 转换为SYSTEMTIME(本地时间,若要UTC用FileTimeToSystemTime直接转)
    SYSTEMTIME st;
    if (!FileTimeToSystemTime(&ft, &st)) {
        fprintf(stderr, "FileTimeToSystemTime failed\n");
        return 1;
    }
    
    // 手动格式化或用Win32的GetDateFormat/GetTimeFormat
    char time_str[100];
    sprintf(time_str, "%02d:%02d:%02d %02d. %02d, %04d",
            st.wHour, st.wMinute, st.wSecond,
            st.wMonth, st.wDay, st.wYear);
    
    printf("Formatted time: %s\n", time_str);
    return 0;
}

注意事项

  • 溢出问题:如果你的1904纪元秒数是32位整数,它只能表示到2036年左右(因为2^32秒约等于136年),建议用64位整数(uint64_t)来存储和计算,避免溢出。
  • 时区差异:localtime和FileTimeToSystemTime默认转换为本地时区时间,如果需要UTC时间,改用gmtime(标准库)或直接使用FileTimeToSystemTime(因为FILETIME本身是UTC的)。

内容的提问来源于stack exchange,提问作者ravin.wang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:20:11