關於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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM