7.各种时间函数的使用


7.1.GMT时间和UTC时间
(1)GMT是格林尼治时间即格林尼治地区的当地时间;我们使用GMT作为全球国际时间,用以描述全球性的事件的时间,方便大家记忆;为了方便,1个国家内都统一使用1个当地时间(譬如北京时间)。
(2)GMT时间是以前使用的,近些年来越来越多的使用UTC时间,关于UTC时间,参考链接http://www.cnblogs.com/qiuyi21/archive/2008/03/04/1089456.html
(3)计算机中有点时间和段时间之分,段时间=点时间-点时间;计算机中与时间有关的部件是定时器和实时时钟;定时器(timer)定的时间就是段时间,实时时钟(RTC)即和点时间有关。


7.2.linux系统如何记录时间
(1)jiffies是linux内核中的1个全局变量,该变量记录以内核的节拍时间为单位时间长度的1个数值;内核配置的时候定义了1个节拍时间,实际上linux内核的调度系统工作时即以该节拍时间作为时间片的;jiffies变量在开机时有1个基准值,然后内核每过1个节拍时间jiffies就会加1,则系统的任意某个时间就被jiffies变量所标注。
(2)内核在开机启动时会读取RTC硬件获取1个时间作为初始基准时间,该基准时间对应1个jiffies值(基准时间-1970-01-01 00:00:00 +0000(UTC)=时间段,时间段/节拍时间=jiffies数值),该jiffies值作为我们开机时的基准jiffies值存在,然后系统运行时在每个节拍时间的末尾都会给jiffies加1,则操作系统即可使用jiffies全局变量记录当前的时间,当我们需要当前时间点时,即使用jiffies时间点去计算(当前jiffies值*节拍时间=时间段,时间段+1970-01-01 00:00:00 +0000(UTC)=当前时间点)。
(3)操作系统只在开机时读1次RTC;jiffies变量记录的其实是段时间(即当前时间-1970-01-01 00:00:00 +0000(UTC)=jiffies变量记录的时间段)。
(4)1个时间节拍的时间取决于操作系统的配置,现代linux系统一般是10ms或者1ms;时间节拍即调度时间,在内核中用HZ来记录和表示;若HZ定义成1000则时钟节拍就是1/HZ即1ms。


7.3.linux中时间相关的函数
(1)常见的与时间相关的API和C库函数有9个:time/ctime/localtime/gmtime/mktime/asctime/strftime/gettimeofday/settimeofday。
(2)time系统调用返回当前时间(以秒为单位)距离1970-01-01 00:00:00 +0000(UTC)过去的秒数;该time函数内部是利用jiffies换算得到的秒数,其余函数基本都是围绕time函数来工作的。
(3)gmtime和localtime会把time得到的秒数变成1个struct tm结构体表示的时间;gmtime得到的是国际时间(UTC时间),localtime得到的是本地时间(即运行localtime函数的程序所在的计算机所设置的时区对应的本地时间);mktime用来完成相反方向的转换(struct tm到time_t)。
(4)若从struct tm出发想得到字符串格式的时间用asctime或strftime函数;若从time_t出发想得到字符串格式的时间用ctime函数。
(5)gettimeofday返回的时间是由struct timeval(表示时间)和struct timezone(表示时区)这两个结构体来共同表示的;settimeofday是用来设置当前的时间和时区的。
(6)不管使用哪个时间函数最终得到的时间本质上都是同一个时间(该时间都是从kernel中记录的jiffies中计算得来的),只是不同的函数返回的时间的格式不同,精度不同(见图1)。


7.4.时间相关API实战
(1)time能得到1个当前时间距离标准起点时间1970-01-01 00:00:00 +0000(UTC)经过的秒数值。
(2)ctime可以从time_t出发得到1个容易观察的字符串格式的当前时间;ctime的好处是很简单好用,可以直接得到当前时间的字符串格式,可直接打印输出,坏处是ctime的打印时间格式是固定的;ctime函数得到的时间是考虑了计算机中的本地时间的(即计算机中的时区设置)。
(3)gmtime获取的时间中年份是以1970为基准的差值,月份中0表示1月,小时数以UTC时间的0时区为标准的小时数(北京是东8区,则北京时间比该时间大8小时);localtime和gmtime的唯一区别就是localtime以当前计算机中设置的时区为小时的时间基准。
(4)mktime是用来向操作系统设置时间时用;asctime得到1个固定格式的字符串格式的当前时间,效果上等同于ctime,区别是ctime从time_t出发,而asctime从struct tm出发;strftime可用户自定义时间的格式。
(5)若我们程序希望得到非常精确的时间(譬如以us为单位),则可通过gettimeofday来实现;settimeofday可设置当前时间和时区信息,只有超级用户可以调用settimeofday,如果存在为NULL的参数,表示不改变某一项信息。


这里写图片描述


7.time_api
/*
 * 公司:XXXX
 * 作者:Rston
 * 博客:http://blog.csdn.net/rston
 * GitHub:https://github.com/rston
 * 项目:各种时间函数的使用
 * 功能:演示各种时间函数的使用。  
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>

int main(int argc, char **argv)
{
    time_t tNow = -1;
    struct tm tmNow;
    char buf[100] = {0};
    struct timeval tv = {0};
    struct timezone tz = {0};
    int ret = -1;

    // 使用time函数
#if 1
    tNow = time(NULL);
#endif
#if 0
    time(&tNow);
#endif
    printf("time: %ld.\n", tNow);           // time: 1468658754.

#if 0   
    // 使用ctime函数
    printf("ctime: %s", ctime(&tNow));      // ctime: Sat Jul 16 01:45:54 2016
#endif

#if 0
    // 使用gmtime
    memset(&tmNow, 0, sizeof(tmNow));
    gmtime_r(&tNow, &tmNow);                // 年116月6日16时8.
    printf("gmtime: 年%d月%d日%d时%d.\n", tmNow.tm_year, tmNow.tm_mon, tmNow.tm_mday, tmNow.tm_hour);
#endif

#if 0   
    // 使用localtime函数
    memset(&tmNow, 0, sizeof(tmNow));
    localtime_r(&tNow, &tmNow);             // 年116月6日16时1.
    printf("localtime: 年%d月%d日%d时%d.\n", tmNow.tm_year, tmNow.tm_mon, tmNow.tm_mday, tmNow.tm_hour);
#endif

#if 0
    // asctime函数
    memset(&tmNow, 0, sizeof(tmNow));
    localtime_r(&tNow, &tmNow); 
    printf("asctime: %s", asctime(&tmNow)); // asctime: Sat Jul 16 06:43:46 2016
#endif

#if 0   
    //  strftime函数
    memset(&tmNow, 0, sizeof(tmNow));
    localtime_r(&tNow, &tmNow); 
    memset(buf, 0, sizeof(buf));
    strftime(buf, sizeof(buf), "%Y * %m * %d, %H-%M-%S.", &tmNow);
    printf("strftime: [%s]\n", buf);
#endif

#if 0   
    // gettimeofday函数
    ret = gettimeofday(&tv, &tz);
    if (ret < 0)
    {
        perror("gettimeofday error");
        exit(-1);
    }
    // seconds: [1468724768].
    // microseconds: [734027].
    // minutes west of Greenwich : [420].
    // type of DST correction: [0].
    printf("seconds: [%ld].\n", tv.tv_sec);
    printf("microseconds: [%ld].\n", tv.tv_usec);
    printf("minutes west of Greenwich : [%d].\n", tz.tz_minuteswest);
    printf("type of DST correction: [%d].\n", tz.tz_dsttime);
#endif

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值