获取当地时间
将时间戳转换为进程当前时区的当地时间;时区通常由 TZ 或系统默认时区决定。“TZ 时间”不是独立的时间标准。
localtime
time_t now = time(NULL);
struct tm *tm_now = localtime(&now);
printf("%04d-%02d-%02d %02d:%02d:%02d\n",
tm_now->tm_year + 1900,
tm_now->tm_mon + 1,
tm_now->tm_mday,
tm_now->tm_hour,
tm_now->tm_min,
tm_now->tm_sec);
localtime_r
适用于多线程,函数原型:
/*
功能:将 time_t 类型的时间戳(自 1970-1-1 的秒数)转换为本地时间的 struct tm 结构体。
timep:指向 time_t 变量的指针。
result(仅 localtime_r):用户提供的 struct tm 存储地址。
*/
struct tm *localtime_r(const time_t *timep, struct tm *result);
例程:
time_t now = time(NULL);
struct tm tm_now;
localtime_r(&now, &tm_now);
获取UTC时间
gmtime
struct tm *gmtime(const time_t *timer); // 非线程安全
gmtime_r
/*
功能:将 time_t 类型的时间戳(自 Epoch 的秒数)转换为UTC 时间(协调世界时)。
timer:指向 time_t 变量的指针。
result(仅 gmtime_r):用户提供的 struct tm 存储地址。
*/
struct tm *gmtime_r(const time_t *timer, struct tm *result);
time_t now = time(NULL); // 获取当前时间戳
struct tm tm_utc; // 用户分配的存储空间
if (gmtime_r(&now, &tm_utc) == NULL)
{
perror("gmtime_r failed");
return -1;
}
printf("UTC 时间:%04d-%02d-%02d %02d:%02d:%02d\n",
tm_utc.tm_year + 1900, tm_utc.tm_mon + 1, tm_utc.tm_mday,
tm_utc.tm_hour, tm_utc.tm_min, tm_utc.tm_sec);
本地时间转换为时间戳:mktime
把 struct tm 中的本地年月日时分秒按当前时区转换为 Unix 时间戳。下面示例显式设置 UTC+8,输出才对应北京时间;POSIX TZ 字符串中的符号方向与 UTC 偏移相反。
/* POSIX 示例:需要 <stdlib.h>、<time.h> 和 <stdio.h>。
TZ 是进程级设置,应在启动阶段配置,避免多线程运行时反复修改。 */
if (setenv("TZ", "CST-8", 1) != 0) {
perror("setenv");
return -1;
}
tzset();
struct tm local = {0};
local.tm_year = 2026 - 1900;
local.tm_mon = 10 - 1;
local.tm_mday = 10;
local.tm_hour = 12;
local.tm_min = 0;
local.tm_sec = 0;
local.tm_isdst = -1;
// 把本地时间转换为 Unix 时间戳
time_t timestamp = mktime(&local);
printf("timestamp = %lld\n", (long long)timestamp);
struct tm utc;
struct tm bj;
gmtime_r(×tamp, &utc);
localtime_r(×tamp, &bj);
printf("UTC: %02d:%02d\n", utc.tm_hour, utc.tm_min);
printf("BJ : %02d:%02d\n", bj.tm_hour, bj.tm_min);
/*
timestamp = 1791604800
UTC: 04:00
BJ : 12:00
*/