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:未知) */
};

需要注意的是 gmtimelocaltime 是标准库内全局变量的首地址,这两个函数共用同一地址,因此当有其中一个函数调用后,其内存将被修改。这两个函数也不能用于多线程的场景中。如果要使用独立的时间结构体 struct tm 来保存信息。请使用 gmtime_rlocaltime_r 函数,具体函数说明请查看 Linux/UNIXman 手册。

基于同一原理 ctimeasctime 返回的字符串也是保存在一个全局的缓冲区中。要多次使用并避免冲突请使用 ctime_rasctime_r 函数代替之。

另外还可以使用 strftime 函数将时间结构体格式化为字符串。函数声明如下:

size_t strftime(char *str, size_t maxsize,
                const char *format,
                const struct tm *timeptr);

format常用格式说明符:

示例:

// 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 

练习:

写程序,输入你的生日年月日,计算从出生到今天已经过了多少天。