在本教程中,我们将展示如何在 C 中使用日期和时间。在本教程中,我们使用 C99。

C 日期时间定义

我们从几个定义开始。日历时间,也称为绝对时间,是时间连续体中的一个点,例如 2016 年 2 月 17 日 13:02:5 CET。时间间隔是两个日历时间之间时间连续体的连续部分,例如 2000 年 2 月 20 日 13:00 到 14:00 之间的小时。经过的时间是间隔的长度,例如 28 分钟。

时间量是经过的时间之和。经过的时间不需要是连续的。当工作花了我们十一个小时,我们可能是在不同的日子工作。CPU 时间是中央处理单元 (CPU) 用于处理计算机程序或操作系统指令的时间量。它以系统时钟或秒为单位进行测量。Unix 纪元是指从1970 年 1 月 1 日 00:00:00 UTC 开始的时间(或 1970-01-01T00:00:00Z ISO 8601)。

Unix 时间是自Unix 纪元以来经过的时间的秒数。 Unix 时间的类型为time_t。另外有一个时间结构体来表示人类可读的日历时间。它由一组包括年、月、日、时、分、秒等变量组成。时间结构体的类型为struct tm

现实时间(Wall time、real-world time、wall-clock time)不同于通过计算机微处理器时钟脉冲或周期测量得到的时间。

time.h包含了以下函数:

  • char *asctime(const struct tm *) — 将时间转化为字符串(过时的)
  • clock_t clock(void) — 返回当前进程启动后使用的CPU时间
  • int clock_getres(clockid_t, struct timespec *) — 返回时钟精度
  • int clock_gettime(clockid_t, struct timespec *) — 用于计算时间,有秒和纳秒两种精度;比clock精确
  • int clock_settime(clockid_t, const struct timespec *) — 设置系统时间
  • char *ctime(const time_t *) — 将时间值转换为日期和时间字符串(过时)
  • double difftime(time_t, time_t) — 计算两个时间的差
  • struct tm *getdate(const char *) — 将时间字符串转换为时间结构体
  • struct tm *gmtime(const time_t *) — 将Unix时间转换为时间结构体(UTC时间
  • struct tm *localtime(const time_t *) — 将Unix时间转换为时间结构体(本地时间)
  • time_t mktime(struct tm *) — 将时间结构体转换为Unix时间
  • size_t strftime(char *, size_t, const char *, const struct tm *) — 以指定格式输出时间字符串
  • char *strptime(const char *, const char *, struct tm *) — 以指定格式的时间字符串配置时间结构体
  • time_t time(time_t *) — 返回Unix时间或设置Unix时间
  • void tzset(void) — 设置时区信息

此外,time.h文件定义了CLOCKS_PER_SEC宏,它保存了每秒的处理器时钟刻度数。 clock_t是进程运行时间类型。

Unix时间(time_t)

Unix时间是指自Unix纪元以来的秒数。 time()函数返回自1970年1月1日协调世界时0小时0分0秒以来的时间值,单位为秒。 如果发生错误,它返回-1。

time_t time(time_t *t);

如果t!=NULL,此函数返回值也会存储到t指向的内存。

#include <stdio.h>
#include <time.h>

// unixtime.c
int main(void) {
    
    time_t now = time(NULL);
    
    if (now == -1) {
        
        puts("The time() function failed");
    }

    printf("%ld\n", now);

    return 0;
}

//❯ ./unixtime
//1638028257

时间结构体(struct tm)

时间结构体是一个人类友好的日期时间。结构体类型为struct tm。函数localtime()可以将 Unix时间(time_t) 转换为时间结构体。他使用本地账户的时区。函数原型如下:

struct tm *localtime(const time_t *clock);

函数存储了一个结构体并返回指针。

下面关于结构tm的描述来自FreeBSD手册。

struct tm {
    int tm_sec;         /* seconds:0-59 */
    int tm_min;         /* minutes:0-59 */
    int tm_hour;        /* hours:0-23 */
    int tm_mday;        /* day of the month:1-31 */
    int tm_mon;         /* month:0-11 */
    int tm_year;        /* year:1900-> */
    int tm_wday;        /* day of the week:0-6 */
    int tm_yday;        /* day in the year:0-365 */
    int tm_isdst;       /* daylight saving time:是否实行夏令时 */
};
#include <stdio.h> 
#include <time.h>       
 
int main(void) {
    
    time_t rawtime = time(NULL);  // 得到Unix时间
    
    if (rawtime == -1) {

        puts("The time() function failed");
        return 1;
    }
    
    struct tm *ptm = localtime(&rawtime);   // 将Unix时间转换为时间结构体
    
    if (ptm == NULL) {
        
puts("The localtime() function failed");
        return 1;
    }
    
    printf("The time is: %02d:%02d:%02d\n", ptm->tm_hour, 
           ptm->tm_min, ptm->tm_sec);

    return 0;
}

//❯ ./brokendowntime 
//The time is: 17:00:12

时间结构体转换为Unix时间

参考

  1. C Date time (zetcode.com)[原文]
  2. clock_gettime的使用,计时比clock()精确 – 木叶火影 – 博客园 (cnblogs.com)
  3. C语言getdate函数、setdate函数的用法 – 简书 (jianshu.com)
最后修改日期: 2021-12-01