3. 时间函数(time.h)
C 语言标准库提供了处理日期和时间的相关函数。使用这些函数能够完成获取和转换时间的操作。
C 语言中标准库中关于时间的核心数据类型是 time_t 类型,它是 long int 类型的别名。它记录的是计算机纪元(1970年1月1日 0:0:0 UTC)至今的秒数。
UTC(Universal Time Coordinated)是协调世界时 是指基于 0 时区的时间。使用 协调世界时 可以解决跨时区问题。
也就是说计算机计时是记录自 1970年1月1日 0:0:0 UTC 时间至今的秒数。每过一秒,此数字加一。
头文件
time.h
常用的时间函数:
函数
说明
time_t time(time_t *tloc);返回计算机元年至今的秒数,如果参数
tloc 不为 NULL 则存入 tloc 指向的地址中。char *ctime(const time_t *timep);给出秒数,返回日历时间的字符串起始地址。
struct tm *gmtime(const time_t *timep);给出 UTC时间 秒数,返回UTC时间结构体的地址。
struct tm *localtime(const time_t *timep);给出 UTC时间 秒数,,返回本地时间结构体地址(由计算机内设置的时区计算得到)
time_t mktime(struct tm *tm);这是 localtime() 的反函数,它根据本地时间结构体内年月日等信息计算UTC时间的秒数并返回。
char *asctime(const struct tm *tm);给出本地时间结构体,返回时间的字符串起始地址。
这里面我们用到了时间结构体 struct tm,其结构体定义 如下:
struct tm {
int tm_sec; /* 秒 [0-60] */
int tm_min; /* 分 [0-59] */
int tm_hour; /* 时 [0-23] */
int tm_mday; /* 月中的天数 [1-31] */
int tm_mon; /* 月[0-11],0代表一月*/
int tm_year; /* 年(实际年份 - 1900) */
int tm_wday; /* 星期几 [0-6],0代表星期日 */
int tm_yday; /* 年中的第几天 [0-365] */
int tm_isdst; /* 夏令时标志(>0:启用,0:禁用,<0:未知) */
};
需要注意的是 gmtime 和 localtime 是标准库内全局变量的首地址,这两个函数共用同一地址,因此当有其中一个函数调用后,其内存将被修改。这两个函数也不能用于多线程的场景中。如果要使用独立的时间结构体 struct tm 来保存信息。请使用 gmtime_r 和 localtime_r 函数,具体函数说明请查看 Linux/UNIX 的 man 手册。
基于同一原理 ctime 和 asctime 返回的字符串也是保存在一个全局的缓冲区中。要多次使用并避免冲突请使用 ctime_r 和 asctime_r 函数代替之。
另外还可以使用 strftime 函数将时间结构体格式化为字符串。函数声明如下:
size_t strftime(char *str, size_t maxsize,
const char *format,
const struct tm *timeptr);
format常用格式说明符:
%Y:年份(如 2023)%m:月份(01-12)%d:日(01-31)%H:小时(00-23)%M:分钟(00-59)%S:秒(00-61,允许闰秒)%A:完整星期名%B:完整月份名%c:本地日期时间表示
示例:
// filename: mytime.c
#include <stdio.h>
#include <time.h>
int main(int argc, char * argv[]) {
time_t now;
struct tm *local_time;
struct tm *utc_time;
char buf[100];
struct tm alarm_time;
time_t alarm_second;
// 获取当前时间的秒数
time(&now);
// 打印当前时间的字符串
printf("当前时间是: %s", ctime(&now)); // ctime返回值指向的字符串自带换行符
// time_t 转为 本地时间结构体
local_time = localtime(&now);
printf("现在是本地时间: %04d-%02d-%02d %02d:%02d:%02d\n",
local_time->tm_year+1900, local_time->tm_mon+1, local_time->tm_mday,
local_time->tm_hour, local_time->tm_sec, local_time->tm_sec);
// time_t 转为 UTC 时间
utc_time = gmtime(&now);
printf("现在是UTC时间: %04d-%02d-%02d %02d:%02d:%02d\n",
utc_time->tm_year+1900, utc_time->tm_mon+1, utc_time->tm_mday,
utc_time->tm_hour, utc_time->tm_sec, utc_time->tm_sec);
// 时间结构体字符串
printf("UTC时间是: %s", asctime(utc_time));
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %A, %B", local_time);
printf("当前时间是: %s\n", buf);
// 计算今天距离 2030 年元旦的秒数
alarm_time = (struct tm){0, 0, 0, 1, 0, 2030-1900};
alarm_second = mktime(&alarm_time);
printf("现在距离 2030年1月1日还有 %ld 秒\n", alarm_second - now);
return 0;
}
编译和运行结果如下:
weimingze@mzstudio:~$ gcc -o mytime mytime.c
weimingze@mzstudio:~$ ./mytime
当前时间是: Sun Dec 7 16:37:10 2025
现在是本地时间: 2025-12-07 16:10:10
现在是UTC时间: 2025-12-07 08:10:10
UTC时间是: Sun Dec 7 08:37:10 2025
当前时间是: 2025-12-07 08:37:10 Sunday, December
现在距离 2030年1月1日还有 128330570 秒
练习:
写程序,输入你的生日年月日,计算从出生到今天已经过了多少天。