• C/C++ 时间知识总结


    C/C++ 中时间的概念

    Unix 时间戳(Unix timestamp),或称 Unix 时间(Unix time)、POSIX 时间(POSIX time),是一种时间表示方式,定义为从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数。time_t 就是用来存储该数的一个类型,它是 unsigned long 类型。使用64位二进制数字表示时间的系统,最多可以使用到格林威治时间292,277,026,596年12月04日15时30分08秒。如果想要更精确一点,可以用结构 struct timeval,它可以精确到微秒:

    struct timeval
    {
        long tv_sec;	// 秒
        long tv_usec; 	// 微秒
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    而直接存储年月日时分秒等的是一个结构体:

    struct tm
    {
        int tm_sec;		// 秒,正常范围0-59, 允许至61
        int tm_min;		// 分钟,0-59
        int tm_hour;	// 小时, 0-23
        int tm_mday;	// 日,一个月中的第几天,1-31
        int tm_mon;		// 月,从一月算起,0-11,1 + p->tm_mon;
        int tm_year;	// 年,从1900至今已经多少年,1900 + p->tm_year;
        int tm_wday;	// 星期,一周中的第几天,从星期日算起,0-6
        int tm_yday;	// 从今年1月1日到目前的天数,范围0-365
        int tm_isdst;	// 日光节约时间的旗标
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    常用的时间库函数

    常用的时间函数都包含在头文件 time.h/ctime(C/C++ 版本)中。

    time()

    time_t time(time_t *ptr);
    
    • 1

    该函数返回得到当前日历时间或者设置日历时间,日历时间即自格林威治时间(1970-01-01 00:00:00 UTC)起经过的时间,单位为秒。ptr 是一个指向类型为 time_t 对象的指针。如果 ptr 不为空,则返回值存储在变量 ptr 中。一般给 ptr 传递0或者 NULL 值,如果传递的是非空地址,也能得到当前的日历时间。

    time_t t1 = time(0);
    time_t t2 = time(NULL);
    // 等价语句,三个对象存储的都是同一个数值
    time_t t3;
    time(&t3);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    asctime()

    char *asctime(const struct tm *timeptr);
    
    • 1

    该函数接受一个指向 tm 结构类型常量对象的指针 timeptr,返回一个指向字符串的指针,该字符串包含了可读格式的日期和时间信息
    w     m     d     h : m : s     y w\ \ \ m\ \ \ d\ \ \ h:m:s\ \ \ y w   m   d   h:m:s   y其中,w 表示星期几,m 是以字母表示的月份,d 表示一月中的第几天,h : m : s 表示当前的时间,y 表示年份。asctime 函数常用于将结构中的信息转换为真实世界的时间,以字符串的形式显示。它计算得到的是世界统一时间。世界统一时间比北京时间早八个小时。比如当前北京时间是 8:41,利用 asctime 显示的时间则为 00:41,这意味着日期也有可能会早一天。

    gmtime()

    struct tm *gmtime(const time_t *timer);
    
    • 1

    该函数接受一个指向 time_t 类型常量对象的指针 timer,返回一个指向 tm 结构类型的指针。它使用 timer 的值来计算 tm 的各个成员变量,得到的是协调世界时

    ctime()

    char *ctime(const time_t *timeptr);
    
    • 1

    该函数接受一个指向 time_t 类型常量对象的指针 timeptr,返回一个指向字符串的指针,其与 asctime() 的返回类型和格式是一样的。这两个函数的区别在于传入的参数类型不一样,而且 ctime 返回的是本地时区时间

    localtime()

    struct tm *localtime(const time_t *timer);
    
    • 1

    该函数接受一个指向 time_t 类型常量对象的指针 timer,返回一个指向 tm 结构类型的指针。它使用 timer 的值来计算 tm 的各个成员变量,得到的是“本地时区时间”。

    mktime()

    time_t mktime(struct tm *timeptr)
    
    • 1

    该函数接受一个指向 tm 结构类型常量对象的指针 timeptr,返回一个 time_t 类型的无符号整数。它的作用是将 timeptr 所指向的结构体变量转换成自格林威治时间(1970-01-01 00:00:00 UTC)起经过的时间并返回,单位为秒,若发生错误返回-1。

    strftime()

    size_t strftime(
    	char *str,
    	size_t maxsize,
    	const char *format,
    	const struct tm *timeptr);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    该函数接受一个字符串str、一个无符号整数 maxsize,一个字符串 format 以及一个指向 tm 结构类型常量对象的指针。它的作用是将 timeptr 表示的时间按照格式化规则存储在 str 中,maxsize 用来表示复制到 str 中的最大字符个数。如果 str 的字符个数(包含空字符 ‘\0’)小于 maxsize,则函数返回其字符个数,否则返回0。

    size_t 是一个与机器相关的无符号整数类型,其大小足以保证存储内存中的任意对象。例如数组下标的类型、vector 下标的类型实际上都是 size_t。

    format 是一个 C 字符串,其中包含了普通字符特殊格式说明符的任何组合。这些格式说明符由 strftime 函数识别,从而将 tm 中每个成员变量(参考前面 tm 结构中定义的各个整数)替换为相应的格式并存入 str 中。下表为格式说明符:

    说明符替换为
    %a缩写的星期几名称,例如:Sun
    %A完整的星期几名称,例如:Sunday
    %b缩写的月份名称,例如:Mar
    %B完整的月份名称,例如:March
    %c日期和时间表示法,例如:Sun Aug 19 02:56:02 2012
    %d一月中的第几天(01-31),例如:19
    %F显示年-月-日,例如:09-11-03
    %H24 小时格式的小时(00-23),例如:14
    %I12 小时格式的小时(01-12),例如:05
    %j一年中的第几天(001-366),例如:231
    %m十进制数表示的月份(01-12),例如:08
    %M十进制表示的分钟数(00-59),例如:55
    %pAM 或 PM 名称,例如:PM
    %r12小时的时间,例如:9
    %R小时和分钟,例如:08:29
    %S秒(00-61),例如:02
    %U一年中的第几周,以第一个星期日作为第一周的第一天(00-53),例如:33
    %w十进制数表示的星期几,星期日表示为 0(0-6),例如:4
    %W一年中的第几周,以第一个星期一作为第一周的第一天(00-53),例如:34
    %x标准日期串,例如:08/19/12
    %X标准时间串,例如:02:50:06
    %y年份的最后两个数字(00-99),例如:01
    %Y完整的年份,例如:2012
    %Z时区的名称或缩写,若得不到时区名称则返回空串,例如:CDT
    %%一个 % 符号,例如:%

    difftime()

    double difftime(time_t time1, time_t time2)
    
    • 1

    该函数接受两个 time_t 类型的无符号整数并返回它们的差值,单位为秒。

    C/C++ 获取当前(本地)时间的方法

    方法一

    先获取格林威治时间,再使用 localtime 函数获取当前时间的 tm 结构类型变量,将其格式化后存入 str 再打印:

    #include 
    #include 
    
    int main(void)
    {
        time_t t = time(0);
        char str[64];
        strftime(str, sizeof(str), "%Y/%m/%d %X %A 今年第%j天 %z", localtime(&t));
        printf("当前时间:%s", str);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    方法二

    先获取格林威治时间,使用 localtime 函数获取当前时间的 tm 结构类型变量,再将其用 ctime 函数转换成当前时间的字符串打印输出:

    #include 
    #include 
    
    int main(void)
    {
        time_t t = time(0);
        struct tm *info = localtime(&t);
    
        printf("当前时间:%s", ctime(info));
    
        return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    方法三

    先获取格林威治时间,使用 localtime 函数获取当前时间的 tm 结构类型变量,然后直接依据 tm 中的成员来计算我们想要打印的内容:

    #include 
    #include 
    
    int main()
    {
        char wday[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
        time_t t = time(0);     // 获得time_t结构的时间,世界协调时
        struct tm *p;
    
        p = localtime(&t);      // 转换为 struct tm 结构的本地时间
        printf("%04d/%02d/%02d ", 1900 + p->tm_year, 1+ p->tm_mon, p->tm_mday);               // 打印当前日期
        printf("%s %02d:%02d:%02d\n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);    // 打印当前时间
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    方法四

    使用 windows 的 API,能够精确到毫秒级。但是因为用的是 windows 下的函数,所以换了其他操作系统就不一定能用了:

    #include 
    #include 
    
    int main()
    {
        SYSTEMTIME sys;
        GetLocalTime(&sys);
        printf("%4d-%02d-%02d %02d:%02d:%02d.%03d 星期%1d",
               sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, sys.wMilliseconds, sys.wDayOfWeek);
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    方法五

    利用系统函数,只显示当前的时间,不显示年月日这些。而且还能直接修改系统时间:

    #include 
    
    int main()
    {
        system("time");
    
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    希望本篇博客能对你有所帮助,也希望看官能动动小手点个赞哟~~。

  • 相关阅读:
    一个简单的网页制作期末作业,学生个人html静态网页制作成品代码
    Docker 入门流程
    外卖配送小程序商城的效果如何
    k8s查看pod日志的几种方法
    修改ctags让fzf.vim插件显示C,C++方法声明的标签
    Oracle事务
    智能云门禁解决方案来了
    Mysql-联合查询及子查询
    排序算法的空间复杂度和时间复杂度
    前端学习笔记——第三天
  • 原文地址:https://blog.csdn.net/qq_37701948/article/details/127652884