1. 程式人生 > >時間日期與時間戳轉換(Linux C)

時間日期與時間戳轉換(Linux C)

一、時間與日期

GMT和UTC

GMT,即格林尼治標準時間,也就是世界時。GMT的正午是指當太陽橫穿格林尼治子午線(本初子午線)時的時間。但由於地球自轉不均勻不規則,導致GMT不精確,現在已經不再作為世界標準時間使用。

UTC,即協調世界時。UTC是以原子時秒長為基礎,在時刻上儘量接近於GMT的一種時間計量系統。為確保UTC與GMT相差不會超過0.9秒,在有需要的情況下會在UTC內加上正或負閏秒。UTC現在作為世界標準時間使用。

所以,UTC與GMT基本上等同,誤差不超過0.9秒。

時區

地球自西向東旋轉,東邊比西邊先看到太陽,東邊的時間也比西邊的早。為了統一世界的時間,1884年的國際經度會議規規定將全球劃分為24個時區(東、西各12個時區)。規定英國(格林尼治天文臺舊址)為零時區(GMT+00),東1-12區,西1-12區,中國北京處於東8區(GMT+08)。

若中國當前時間為8點整,則英國時間為0點整。

UNIX時間戳

由Unix核心提供的基本時間服務是自國際標準時間公元1970年1月1日00:00:00以來的秒數。

二、時間字串相互轉換

時間戳轉換為格式化日期

流程: time_t(日曆時間) ——->struct tm(以年月日、時分秒錶示的時間)——>格式化字串(利用strftime函式)

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

int main(int argc, const char * argv[])  
{  
    time_t t;  
    struct tm *p
; t=0; p=gmtime(&t); char s[100]; strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", p); printf("%d: %s\n", (int)t, s); return 0; }

結果:
1970-01-01 00:00:00

格式化日期轉換為時間戳

流程: struct tm(以年月日、時分秒錶示的時間) —> time_t(日曆時間)

#include <stdio.h>  
#include <time.h>  
#include <stdlib.h> int main(int argc, const char * argv[]) { struct tm* tmp_time = (struct tm*)malloc(sizeof(struct tm)); strptime("19700101080000","%Y%m%d%H%M%S",tmp_time); //時間24時制 time_t t = mktime(tmp_time); printf("%ld\n",t); free(tmp_time); return 0; }

結果:
0

這裡並沒有把時間設定為1970年1月1日0點,因為這裡涉及到時區的問題。我們目前處於東八區,計算時需要減去8小時。

三、環境變數TZ及時區設定函式

在UNP書裡講過,時間函式除了gmttime()、asctime()不受環境變數TZ的影響外,大部分函式都受到環境變數TZ的影響,這幾個函式是: localtime、mktime、ctime和strftime。如果定義了TZ,則這些函式將使用其值以代替系統預設時區。

在Unix環境下可以通過改變系統檔案修改環境變數,也可以通過函式setenv()修改。

TZ指定了當前的系統時區。這個時區會影響我們所做的時間轉換。例如假設當前的系統時間是8:00AM,如果我們把當前的時區設定成東八區,則標準時間就是(即GMT+0)的時間就是8-8=0:00AM,如果是看成是東6區的話,則標準時間就變成了8-6=2:00AM。

時區設定函式是: setenv(“TZ”, “GMT+0”, 1);//將當前時區設定成標準區
setenv(“TZ”, “GMT-8”, 1); 表示的意思就是:將當前時區設定成東八區。需要注意的是,這裡要寫成GMT-8才是東八區,不是GMT+8,原因GMT表示時間的方式有點不同,它的格式是(GMT[+/-]offset), 如果目標時區是在東區,則是負的,否則是正的。意思就是本地時區加減多少(offset)才能得到標準時間。

程式碼:

#include <stdio.h>  
#include <time.h>  
#include <stdlib.h>    
int main(int argc, const char * argv[])  
{  
    setenv("TZ", "GMT-8", 1);//時區設定為東8區
    //setenv("TZ", "GMT+0", 1);//將當前時區設定成標準區
    struct tm* tmp_time = (struct tm*)malloc(sizeof(struct tm));  
    strptime("19700101080000","%Y%m%d%H%M%S",tmp_time); //時間24時制
    time_t t = mktime(tmp_time);  
    printf("%ld\n",t);  
    free(tmp_time);  
    return 0;  
}  

當時區設定為東8區時,我們標準時間為8-8=0小時,轉換為秒數為:0
當時區設定為國際標準時,標準時間即為8-0=8小時,轉換為秒數為:(8-0)*3600=28800