zoukankan      html  css  js  c++  java
  • C++时间函数小结

    time

    time_t time (time_t* timer);
    返回的值表示自1970年1月1日0时0分0秒(这个时间名叫 The Unix Epoch)起,到现在过去的时间,这里C/C++标准中并没有规定精度单位(linux和windows中单位是秒),也没有规定time_t的类型长度。
    当time_t是32位有符号整型的时候,并且时间单位是秒,那么最大只能表示2038年1月19日3时14分8秒,也就是Y2038问题。
    但在64位linux和windows上,time_t都是64位的,所以不用担心溢出问题,但是我在raspbian32位系统上测试,time_t是32位的,所以可能业界以后还是会引入新的类型来解决这一问题吧,或者升级64位操作系统就是解决方案?

    gettimeofday

    int gettimeofday(struct timeval *tv, struct timezone *tz);
    同样也是获取自1970年1月1日0时0分0秒,到现在过去的时间。并且将结果写入timeval结构中:

    struct timeval {
        time_t      tv_sec;     /* seconds */
        suseconds_t tv_usec;    /* microseconds */
    };
    

    timezone参数已经过时了,所以直接传入nullptr即可。下面是使用gettimeofday的代码示例:

    /**
     * 返回自unix时间戳(unix epoch)到现在经过的时间(ms)
     * @return 自unix时间戳到现在经过的时间(ms)
     * @note 若time_t为32位,会有Y2038问题,如果只是用于计算时间差影响不大
     */
    uint64_t utcTime() noexcept {
        // struct timeval {
        //      time_t tv_sec;        /* seconds */
        //      suseconds_t tv_usec;  /* microseconds */
        // }
        // 64位linux和windows中,time_t都是64位的,但一些32位系统time_t为32位,最多只能计数到2038年
        struct timeval tv;
        gettimeofday(&tv, nullptr);
        return tv.tv_sec * 1000 + tv.tv_usec / 1000;
    }
    

    日期转字符串

    时间戳转为字符串分为两步:

    1. struct tm *localtime(const time_t *timep)将time_t转换为tm结构体;
    2. size_t strftime(char *s, size_t max, const char *format,const struct tm *tm)将tm结构体转换为指定格式字符串输出;

    tm结构体:

    成员 类型 含义 取值范围
    tm_sec int 秒数 0-60*
    tm_min int 分钟 0-59
    tm_hour int 小时 0-23
    tm_mday int 日期 1-31
    tm_mon int 月份 0-11
    tm_year int 年份
    tm_wday int 星期几 0-6
    tm_yday int 今年的第几天 0-365
    tm_isdst int 夏令时标志

    常用日期输出格式控制符:

    控制符 说明 示例
    %Y 年份 2020
    %y 年份后两位 20
    %m 月份(01-12) 04
    %d 日期(01-31) 05
    %H 24小时(00-23) 23
    %I 12小时(01-12) 11
    %M 分钟(00-59) 23
    %S 秒数(00-59) 45

    这里使用strftime时需要注意,该函数不是线程安全的,因为使用了全局共享的空间去返回结果。这时可以用linux和windows的可重入替代版本:

    • linux:struct tm *localtime_r(const time_t *timep, struct tm *result)
    • windows:struct tm *localtime_s(struct tm *result, const time_t *timep)

    可以看到linux和windows的功能都是一样的,只是参数顺序不同。

    字符串转日期

    在linux系统上提供了char *strptime(const char *s, const char *format, struct tm *tm)函数,可以将字符串转换为tm结构体。
    再用mktime就可以将tm结构体转换为time_t了,这里重点讲一下这个mktime,首先它会忽略掉tm_wdaytm_yday成员,然后会自动纠正里面的错误,比如tm_mday天数设置为32超了一天,那么mktime会自动将其理解为下一个月的第一天。最后会将修正后的信息改写如传入的tm结构体中。

  • 相关阅读:
    SQL语句之奇形怪状的冷门函数
    计算累计收益
    关于SQL表字段值缺失的处理办法
    虚拟机移植到另一台机器
    分分钟搞懂rank() over(partition by)的使用
    分分钟搞懂union与union all
    【转】10分钟就能学会的.NET Core配置
    【转】依赖注入的威力,.NET Core的魅力:解决MVC视图中的中文被html编码的问题
    【转】Asp.Net Core2.0获取客户IP地址,及解决发布到Ubuntu服务器获取不到正确IP解决办法
    【转】在.net Core 中像以前那样的使用HttpContext.Current
  • 原文地址:https://www.cnblogs.com/HachikoT/p/12611237.html
Copyright © 2011-2022 走看看