7.各种时间函数的使用

来源:互联网 发布:域名申请步骤 编辑:程序博客网 时间:2024/05/25 08:13

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