关于linux的时间表示函数:localtime、gmtime、ctime、strftime。

 首先得理解一下关于时间表示的基本概念,不搞清楚基本概念,过段时间还会是一团糨糊。理解了基本概念后,再来看这几个函数,就很简单明了了。


1、基本概念:

1.UTC(universal time coordinated)称为协调时间时,是国际无线电咨询委员会制定和推荐的,以子午初线(经度0度)上的平均太阳时为依据,也就是英国伦暾的平均太阳时。

2.GMT(greenwitch mean time)格林威治平均时间,由于地球绕太阳的轨道不是圆形的,而且自转轴相对轨道面是倾斜的,导致UTC的表示不是很精确,为此提出了GMT时间,通过每一年或两年对UTC加一个闰秒完成修正,我们一般认为GMT和UTC是一样的,下方统一称为UTC;

3、Calendar Time:日历时间,是用“从一个标准时间点到此时的时间经过的秒数”来表示的时间。无论哪一个时区,在同一时刻对同一个标准时间点来说,日历时间都是一样的。日历时间返回自1970-1-1:00:00:00以来所经过的秒数累计值。因此,不论服务器是在那个时区(国家),同一时刻,日历时间总是一样的,都是相对于1970-1-1:00:00:00以来的秒数,理解这点很重要,如果不理解,想想多出来的秒数是那里来的...

4、时区(本地时间)
为了克服时间上的混乱,1884年在华盛顿召开的一次国际经度会议(又称国际子午线会议)上,规定将全球划分为24个时区(东、西各12个时区)。规定英国(格林尼治天文台旧址)为中时区(零时区)、东1-12区,西1-12区。每个时区横跨经度15度,时间正好是1小时。最后的东、西第12区各跨经度7.5度,以东、西经180度为界。每个时区的中央经线上的时间就是这个时区内统一采用的时间,称为区时,相邻两个时区的时间相差1小时。例如,中国东8区的时间总比泰国东7区的时间早1小时,而比日本东9区的时间迟1小时。因此,出国旅行的人,必须随时调整自己的手表,才能和当地时间相一致。

我是这样理解的,因为时区的划分是以太阳升起的时间。比如我每天早上7点起床,8点吃早餐,9点上班。当出差美国,于是将手机/手表调到美国当地时间,依然是早上7点起床(太阳也是某个高度),8点吃早餐,9点上班。作息时间不变,可是国内是大白天的时候,美国正是深夜。在不同时区上的白天、黑夜,对个人的感受是一样的,但日历时间是不一样的,两地方的日历时间相减得到的时间差,就是时差了。

知道UTC与地区时间,有如下的换算关系:地区时间=UTC+时区差
东区是加相应的时区差,西区是减时区差。如北京是东八区,则北京时间=UTC+8;

 

2、实例:本地时间 = UTC + 时差

root@ubuntu:~/vm_disk_dpdk/study# date -u; date -R
Thu Dec 24 06:27:11 UTC 2015
Wed, 23 Dec 2015 22:27:11 -0800
本机所配置的时区是西八区(负号表示为西区)
 UTC时间为Dec 24 06:27:11,本地时间为23 Dec 2015 22:27:11,等于UTC-8.
 
 root@ubuntu:~/vm_disk_dpdk/study# cp /usr/share/zoneinfo/Asia/Chongqing /etc/localtime  //更改系统时区
root@ubuntu:~/vm_disk_dpdk/study# date -u; date -R
Thu Dec 24 06:53:13 UTC 2015
Thu, 24 Dec 2015 14:53:13 +0800

root@ubuntu:~/vm_disk_dpdk/study# cp /usr/share/zoneinfo/Africa/Abidjan /etc/localtime
root@ubuntu:~/vm_disk_dpdk/study# date -u; date -R
Thu Dec 24 06:54:17 UTC 2015
Thu, 24 Dec 2015 06:54:17 +0000

root@ubuntu:~/vm_disk_dpdk/study# cp /usr/share/zoneinfo/America/New_York /etc/localtime
root@ubuntu:~/vm_disk_dpdk/study# date -u; date -R
Thu Dec 24 06:55:16 UTC 2015
Thu, 24 Dec 2015 01:55:16 -0500


3、time、localtime、gmtime & ctime (man mktime能更多信息)

time函数返回的是日历时间。

localtime&gmtime这两个函数的参数都是日历时间,当换算成日期、时间时,对于localtime需要考虑时区。UTC时间,就是日历时间加上1970-1-1:00:00:00即可。

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

void test_time()
{
    time_t tm = 1450942746;    
    //tm = time(NULL);
printf(
"calendar times = %lu seconds\n", tm); printf("localtime(&tm):\t%s", asctime(localtime(&tm))); printf("gmtime(&tm):\t%s", asctime(gmtime(&tm))); printf("ctime:\t\t%s\n", ctime(&tm)); } int main() { test_time(); return 0; }

 

 通过更改系统时区测试两次,再次打印的gmt时间都是一样的(因为日历时间是一样的),而localtime是不一样(localtime=gmtime(UTC)+  时区)。

root@ubuntu:~/vm_disk_dpdk/study/apue/sys_info# cp /usr/share/zoneinfo/Africa/Djibouti /etc/localtime
root@ubuntu:~/vm_disk_dpdk/study/apue/sys_info# date -R           
Thu, 24 Dec 2015 10:58:39 +0300
root@ubuntu:~/vm_disk_dpdk/study/apue/sys_info# ./a.out
calendar times = 1450942746 seconds
localtime(&tm): Thu Dec 24 10:39:06 2015  //本地时间=utc+时区
gmtime(&tm):    Thu Dec 24 07:39:06 2015  //两次测试的UTC时间是一样的
ctime:          Thu Dec 24 10:39:06 2015
    
    
root@ubuntu:~/vm_disk_dpdk/study/apue/sys_info# cp /usr/share/zoneinfo/America/Grenada /etc/localtime
root@ubuntu:~/vm_disk_dpdk/study/apue/sys_info# date -R
Thu, 24 Dec 2015 03:44:40 -0400
root@ubuntu:~/vm_disk_dpdk/study/apue/sys_info# ./a.out
calendar times = 1450942746 seconds
localtime(&tm): Thu Dec 24 03:39:06 2015
gmtime(&tm):    Thu Dec 24 07:39:06 2015
ctime:          Thu Dec 24 03:39:06 2015

 

5、strftime, time、ctime、mktime (man mktime能更多信息)

time函数返回的是日历时间。

ctime: ctime(t) 等价于 asctime(localtime(t)).

mktime函数的输入参数应该是本地时间而非UTC时间。附:The  mktime() function converts a broken-down time structure, expressed as local time, to calendar time representation.

strftime类型sprintf,格式串的定义参考man strftime

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

void test_time()
{
    time_t tm ;
    tm = time(NULL);   
    printf("calendar times = %lu seconds\n", tm);    
    printf("mktime(localtime(&tm)):\t%lu\n", mktime(localtime(&tm)));
    printf("mktime(gmtime(&tm)):\t%lu\n\n", mktime(gmtime(&tm)));

    printf("asctime(localtime(&tm))=%s", asctime(localtime(&tm)));
    printf("ctime(&tm))=\t\t%s\n", ctime(&tm));
    
    char buf[100];
    strftime(buf, 100, "%a, %d %b %Y %T %z", localtime(&tm));
    printf("strftime: %s\n",buf);
}

int main()
{
    test_time();    
    return 0;
}

 

root@ubuntu:~/vm_disk_dpdk/study/apue/sys_info# ./a.out         
calendar times = 1450947508 seconds
mktime(localtime(&tm)): 1450947508  //由此可验证,mktime输入的应该是本地时间,此值等于之前的日历时间
mktime(gmtime(&tm)):    1450961908  //The  mktime() function converts a broken-down time structure, expressed as local time, to calendar time representation.

asctime(localtime(&tm))=Thu Dec 24 04:58:28 2015  // ctime(t) is equivalent to asctime(localtime(t))
ctime(&tm))=              Thu Dec 24 04:58:28 2015

strftime: Thu, 24 Dec 2015 04:58:28 -0400

 

posted on 2015-12-24 17:01  marvin.li  阅读(7185)  评论(0编辑  收藏  举报

导航