/ taohigo.com / 0浏览

時間時區概念及常用時間函數

時區,為瞭克服時間上的混亂,1884年在華盛頓召開的一次國際經度會議(又稱國際子午線會議 )上,規定將全球劃分為24個時區(東、西各12個時區)。規定英國(格林尼治天文臺舊址)為中時區(零時區)、東1-12區,西1-12區,每個時區橫跨經度15度,時間正好是1小時。最後的東、西第12區各跨經度7.5度,以東、西經180度為界。每個時區的中央經線上的時間就是這個時區內統一采用的時間,稱為區時,相鄰兩個時區的時間相差1小時。

硬件時鐘(又稱實時時鐘,也就是RTC),實時時鐘為操作系統提供瞭一個可靠的時間,並且在斷電的情況下,RTC實時時鐘也可以通過電池供電,一直運行下去,用來保存和同步計算機操作系統時間。RTC通過STRB/LDRB這兩個ARM指令向CPU傳送8位數據(BCD碼)。數據包括秒,分,小時,星期,天,月和年。RTC實時時鐘依靠一個外部的石英晶體,產生周期性的脈沖信號,每一個信號到來時,計數器就加1,通過這種方式,完成計時功能。

系統時鐘,操作系統認知的時間,包括時區信息和UTC時間(unix時戳均使用1970年1月1日0時0分0秒到目前的UTC秒數)兩部分,時區信息保存在/etc/localtime文件中,一般由/usr/share/zoneinfo/目錄下的時區文件拷貝或鏈接而來(該目錄包含所有支持的時區文件,修改時區其實是替換/etc/localtime文件,而不是直接修改該文件內容)。UTC時間是UNIX系統所使用的標準時間,不同地區的人使用時顯示的本地時間由UTC+時區而來(也可以說所有Unix/linux操作系統的系統時間都相同,1970年1月1日0時0分0秒到目前的UTC秒數)。

瞭解以上概念我們知道,計算機系統一般包括三個重要的時間(也是容易搞混的時間,通常我們所說的計算機時間應該指的是本地時間,用戶在第一次使用設備時需要選擇時所在區),分別為硬件rtc時間,系統utc時間和本地local時間。三者有以下關系:

硬件rtc時間是在關機或掉電狀態能夠繼續保存的,所以為主導地位,其他時間都可以由該時間計算得來(系統時間在操作系統運行起來後被rtc同步),rtc保存的時間可以有兩種,一是utc時間,二是local時間,以東八區為例:

當rtc時間為utc時間:系統utc時間 = rtc時間, 本地local時間 = rtc時間 + 8小時;

當rtc時間為local時間:系統utc時間 = rtc時間 – 8小時, 本地local時間 = rtc時間 ;

兩種設置都可以,沒有明確規定,不過一般Windows和Linux都默認rtc保存local本地時間。

linux時間結構體定義:

struct tm

{

int tm_sec;

int tm_min;

int tm_hour;

int tm_mday;

int tm_mon;

int tm_year;

int tm_wday;

int tm_yday;

int tm_isdst;

};

int tm_sec 代表目前秒數,正常范圍為0-59,但允許至61秒

int tm_min 代表目前分數,范圍0-59

int tm_hour 從午夜算起的時數,范圍為0-23

int tm_mday 目前月份的日數,范圍01-31

int tm_mon 代表目前月份,從一月算起,范圍從0-11

int tm_year 從1900年算起至今的年數

int tm_wday 一星期的日數,從星期一算起,范圍為0-6

int tm_yday 從今年1月1日算起至今的天數,范圍為0-365

int tm_isdst 日光節約時間的旗標

timeval結構定義為:

struct timeval

{

long tv_sec; /*秒*/

long tv_usec; /*微秒*/

};

timezone結構定義為:

struct timezone

{

int tz_minuteswest; /*和Greenwich 時間差瞭多少分鐘*/

int tz_dsttime; /*日光節約時間的狀態*/

};

linux常用時間函數介紹:

1、time(取得當前時間UTC秒數,無時區轉換)

#include<time.h>

time_t time(time_t *t);

這個函數應該算是最常用函數之一,返回UTC標準秒數,沒有時區轉換,在倫敦和上海同時調用這個函數返回值相同。

2、gmtime(獲取當前時間結構,UTC時間,無時區轉換)

#include<time.h>

struct tm *gmtime(const time_t *timep);struct tm *gmtime_r(const time_t *timep, struct tm *result);

這兩個函數意思一樣,將timep這個秒數轉換成以UTC時區為標準的年月日時分秒時間。gmtime_r是線程安全的,推薦使用這個。gmtime返回的是一個structtm*,這個指針指向一個靜態的內存,這塊區域是會經常被改動的。你剛調用gmtime(),執行瞭其他幾條命令,然後想使用剛才gmtime()得到struct tm,會發現內容不對瞭,所以很危險,使用gmtime_r後就沒有問題,gmtime_r會將結果保存到你傳入的內存中。

3、localtime(獲取當前時間結構,本地時間,有時區轉換)

#include<time.h>

struct tm *localtime(const time_t * timep);struct tm *localtime_r(const time_t *timep, struct tm *result);

這兩個函數意思也一樣,會根據時區信息得到本地時間,同樣建議使用localtime_r版本。

4、mktime(將時間結構轉換為UTC秒數,有時區轉換)

#include<time.h>

time_t mktime(struct tm *tm);

將已經根據時區信息計算好的structtm轉換成time_t的秒數。計算出的秒數是以UTC時間為標準的,跟調用time()得到的秒數是同一個概念。

5、gettimeofday(獲取當前時間,UTC時間,精度微妙,無時區轉換)

#include <sys/time.h>

#include <unistd.h>

int gettimeofday(struct timeval *tv, struct timezone *tz);

這個timeval是相對time_t更精確的時間,包含瞭微妙數。tv_usec最大為999999,再加1則為1秒,超過1秒就進位到tv_sec。timezone一般傳入NULL,linux沒有處理timezone中的tz_dsttime信息,所以在編程時不要從這裡獲取時區信息。

6、ctime(將時間轉換為本地時間字符串, 有時區轉換)

#include<time.h>

char *ctime(const time_t *timep);

7、asctime(將時間轉換為字符串, 無時區轉換)

#include<time.h>

char *ctime(const time_t *timep);

char * asctime(const struct tm * timeptr);

代碼示例:

#include <stdio.h>

#include <time.h>

#include <sys/time.h>

int main(int argc, char* argv[])

{

time_t timep;

time(&timep);//獲取UTC秒數

//ctime轉換為本地時間字符串形式,有時區轉換

printf("timep = %ld, local time = %s", timep, ctime(&timep));

struct timeval tv;

gettimeofday(&tv, NULL);//獲取微秒精度時間結構,UTC無時區轉換

printf("tv.sec = %ld, tv.usec = %ldn", tv.tv_sec, tv.tv_usec);

struct tm result_gmtime, result_localtime;

gmtime_r(&timep, &result_gmtime);//獲取UTC時間結構,無時區轉換

localtime_r(&timep, &result_localtime);//獲取本地時間結構,有時區轉換

//時間結構轉換為字符串顯示,無時區轉換

printf("gmtime_r = %s", asctime(&result_gmtime));

printf("localtime_r = %s", asctime(&result_localtime));

//mktime將本地時間轉換為UTC秒數,有時區轉換

printf("mktime localtime to utc = %ldn", mktime(&result_localtime));

//錯誤值示范,本身是UTC,再減時區結果是錯誤的

printf("mktime localtime to utc = %ldn", mktime(&result_gmtime));

return 0;

}

執行結果:

timep = 1471929196, local time = Tue Aug 23 13:13:16 2016

tv.sec = 1471929196, tv.usec = 146952

gmtime_r = Tue Aug 23 05:13:16 2016

localtime_r = Tue Aug 23 13:13:16 2016

mktime localtime to utc = 1471929196

mktime localtime to utc = 1471900396

可見最後一行時間打印是個錯誤值。

————————————————

版權聲明:本文為CSDN博主「Study楊」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:時間時區概念及常用時間函數_Study楊的博客-CSDN博客_gmtime_r

裝修幹貨|什麼是自流平地面?裝修必學的知識
裝修幹貨|什麼是自流平地面?裝修必學的知識
《絕命快遞》——超適合雙十一後看的電影!
《絕命快遞》——超適合雙十一後看的電影!
電路基礎(第一章電路模型和電路定律)
電路基礎(第一章電路模型和電路定律)
智能機器人制作全攻略
智能機器人制作全攻略
詞匯專欄|staff的正確用法
貓眼石不一般的靈性與功效!
貓眼石不一般的靈性與功效!

0

  1. This post has no comment yet

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注