C Unix 时间戳代码片段
C 示例,用于获取当前 Unix 时间戳、用 strftime() 将纪元秒转换为可读日期,以及用 timegm() 从日历日期构建时间戳。
#include <time.h>
time_t ts = time(NULL);#include <time.h>
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
long ms = (long)ts.tv_sec * 1000L + ts.tv_nsec / 1000000L;#include <time.h>
#include <stdio.h>
time_t ts = 1700000000;
struct tm *tm_info = gmtime(&ts); // UTC
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm_info);
printf("%s\n", buf); // "2023-11-15 06:13:20"#include <time.h>
time_t ts = 1700000000;
struct tm *tm_info = localtime(&ts); // host timezone
char buf[64];
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm_info);#define _GNU_SOURCE
#include <time.h>
struct tm t = {0};
t.tm_year = 2023 - 1900; // years since 1900
t.tm_mon = 10; // 0-indexed; 10 = November
t.tm_mday = 15;
t.tm_hour = 6;
t.tm_min = 13;
t.tm_sec = 20;
time_t ts = timegm(&t); // GNU/POSIX; use mktime() for local#include <time.h>
time_t start = time(NULL);
/* ... work ... */
time_t end = time(NULL);
double elapsed = difftime(end, start);C 时间戳基础
C 用 time_t 表示 Unix 时间,它是定义在 <time.h> 中的有符号整数类型。在 64 位系统上,time_t 是 64 位,免受 2038 年溢出影响。在 32 位系统上,许多平台仍是 32 位;用 sizeof(time_t) 确认。标准函数 time(NULL) 以秒返回当前 Unix 时间。
gmtime 与 localtime
gmtime() 把 time_t 转换为 UTC 的 struct tm。localtime() 转换为主机系统的本地时区。当你需要可复现、与时区无关的结果时,始终使用 gmtime()。两个函数都返回指向共享静态 struct 的指针;如果你需要跨函数调用使用,请把结果复制到一个本地 struct tm 变量中。
C 生产注意事项
对于亚秒精度,优先使用 clock_gettime(CLOCK_REALTIME) 而非 gettimeofday();POSIX 把 gettimeofday() 标记为过时。把日历日期转换为 UTC 时间戳时,使用 timegm()(GNU/BSD)或可移植的等价物;mktime() 把输入解释为本地时间,在非 UTC 环境中会悄然产生错误结果。
- 在嵌入式目标上检查 sizeof(time_t);32 位 time_t 在 2038 年 1 月回绕
- 在多线程代码中使用 gmtime_r() 和 localtime_r() 以避免数据竞争
- strftime() 格式字符串与区域设置无关;为互操作性,优先用 %Y-%m-%d 而非 %x
- timegm() 不在 POSIX 中;在 Windows 上用 _mkgmtime(),或用 mktime() + UTC 偏移手动实现
转换 Linux 时间:date(1)、time_t、gmtime、strftime
搜索「convert linux time」或 Linux 时间戳转换通常指 shell 命令 date(1) 或下面的 C 库 time_t 函数。Linux 把 Unix 时间戳存为 time_t——旧系统上是有符号 32 位(Y2038 限制),现代系统上是有符号 64 位。
- Shell (GNU date):date -u -d @1700000000 — epoch → UTC 日期时间
- Shell (BSD/macOS):date -ur 1700000000 — 注意是 -r 而非 -d @
- Shell 当前 epoch:date +%s(秒),date +%s%3N(毫秒,仅 GNU)
- C 库:time_t t = time(NULL); struct tm *u = gmtime(&t); strftime(buf, sizeof(buf), '%Y-%m-%dT%H:%M:%SZ', u);
- C 库:timegm(struct tm *) 返回一个对应 UTC 日历时间的 time_t
- POSIX time_t:有符号 32 位在 2038-01-19 溢出;64 位 time_t 是现代的修复
Linux 纪元时间、Linux 时间戳转时间、在线 Linux 转换器
变体:「linux epoch time」(Linux 上的 Unix 时间)、「linux timestamp to time」(epoch → 挂钟)、「linux timestamp converter online」(本页)。
- Linux epoch time / linux epoch time — 与 Unix 时间相同;当前值:date +%s
- Linux timestamp to time / linux timestamp to time — date -u -d @1700000000 返回 UTC 挂钟时间
- Linux timestamp converter online / linux timestamp converter online — 本页是 date(1) 的浏览器版等价物
FAQ
- 在 C 中 Unix 时间戳应使用什么类型?
- 秒精度用 time_t,需要存储毫秒或纳秒时用 int64_t(来自 <stdint.h>)。避免使用 int 或 long,因为它们的大小依赖于平台。
- 在 C 中如何获取毫秒?
- 使用 <time.h> 的 clock_gettime(CLOCK_REALTIME, &ts)。结果在 ts.tv_sec(秒)和 ts.tv_nsec(纳秒)中。毫秒按 ts.tv_sec * 1000LL + ts.tv_nsec / 1000000 计算。