C語言中時鍾編程


C語言中時鍾編程

1. 文章目的

由於最近在研究RTC,所以需要利用到C語言中的時間函數。本文從x1000的rtc時鍾出發,研究C語言中時鍾函數的使用與在rtthread中如何設置並且讀取rtc時鍾。

2.基本概念

2.1 UTC時間

整個地球分為二十四時區,每個時區都有自己的本地時間。在國際無線電通信場合,為了統一起見,使用一個統一的時間,稱為通用協調時(UTC, Universal Time Coordinated)。UTC與格林尼治平均時(GMT, Greenwich Mean Time)一樣,都與英國倫敦的本地時相同。在本文中,UTC與GMT含義完全相同。
我們可以認為格林威治時間就是時間協調時間(GMT=UTC),格林威治時間和UTC時間均用秒數來計算的。
北京時區是東八區,領先UTC八個小時,在電子郵件信頭的Date域記為+0800。如果在電子郵件的信頭中有這么一行:
Date: Fri, 08 Nov 2002 09:42:22 +0800
說明信件的發送地的地方時間是二○○二年十一月八號,星期五,早上九點四十二分(二十二秒),這個地方的本地時領先UTC八個小時(+0800, 就是東八區時間)。電子郵件信頭的Date域使用二十四小時的時鍾,而不使用AM和PM來標記上下午。

2.2 UNIX紀元時間

在計算機中看到的UTC時間都是從(1970年01月01日 0:00:00)開始計算秒數的。所看到的UTC時間那就是從1970年這個時間點起到具體時間共有多少秒。 這個秒數就是Unix時間戳。
說到UNIX時間不得不提Unix 2038 bug(Jason hatchet bug):2038年1月19日3時14分07秒,32位元系統的UNIX時間將會被重置。
32位的UNIX系統會以32位二進制數字表示時間,它們最多只能表示至協調世界時間2038年1月19日3時14分07秒(二進 制:01111111 11111111 11111111 11111111),在下一秒二進制數字會是10000000 00000000 00000000 00000000,這是負數,因此各系統會把時間誤解作1901年12月13日20時45分52秒(亦有說回歸到1970年)。這時可能會令軟件發生問 題,導致系統癱瘓。
目前解決方案是把系統由32位轉為64位系統。在64位系統下,此時間最多可以表示到292,277,026,596年12月4日15時30分08秒。

2.3 格林威治時間 (GMT)

格林尼治是英國倫敦南郊原皇家格林尼治天文台所在地,地球本初子午線的標界處,世界計算時間和經度的起點。以其海事歷史、作為本初子午線的標准點、以及格林尼治時間以其命名而聞名於世。這里地勢險要,風景秀麗,兼具歷史和地方風情,也是倫敦在泰晤士河的東方門戶。
不光是天文學家使用格林尼治時間,就是在新聞報刊上也經常出現這個名詞。我們知道各地都有各地的地方時間。如果對國際上某一重大事情,用地方時間來記錄,就會感到復雜不便.而且將來日子一長容易搞錯。因此,天文學家就提出一個大家都能接受且又方便的記錄方法,那就是以格林尼治的地方時間為標准。
以本初子午線的平子夜起算的平太陽時。又稱格林尼治平時或格林尼治時間。各地的地方平時與世界時之差等於該地的地理經度。1960年以前曾作為基本時間計量系統被廣泛應用。由於地球自轉速率曾被認為是均勻的,因此在1960年以前,世界時被認為是一種均勻時。由於地球自轉速度變化的影響,它不是一種均勻的時間系統,它與原子時或力學時都沒有任何理論上的關系,只有通過觀測才能對它們進行比較。后來世界時先后被歷書時和原子時所取代,但在日常生活、天文導航、大地測量和宇宙飛行等方面仍屬必需;同時,世界時反映地球自轉速率的變化,是地球自轉參數之一,仍為天文學和地球物理學的基本資料。

3.時間轉換

由於機器時間不是人類能夠識別的,所以要講機器時間轉換成大家都能識別的時分秒形式。
下面是一些經常用到的時間函數:

asctime(將時間和日期以字符串格式表示); ===>傳入UTC(struct tm)tmp,返回char*。
ctime(將時間和日期以字符串格式表示); ===>傳入(time_t)arg,返回char*。
gettimeofday(取得目前的時間); ===>傳入(time_t)arg,返回tv,tz結構體傳入時間,時區信息。
gmtime(取得目前時間和日期); ===>傳入(time_t)arg,返回UTC(struct tm)tmp。
localtime(取得當地目前時間和日期); ===>傳入time_t,返回當地(struct tm)tmp。
mktime(將時間結構數據轉換成經過的秒數); ===>把(struct tm)tmp轉換為UTC(time_t)arg。
settimeofday(設置目前時間); ===>通過tv,tz結構體傳入時間,時區信息。
time(取得目前的時間); ===>非空參數(或返回值)接收(time_t)arg。

×××注1:char*是字符串時間格式。如:Sat Oct 28 02:10:06 2000。
×××注2:time_t是time()的返回值類型,(time_t)arg指從1970年到所指時間的秒數。
×××注3:struct tm為真實世界的表示時間方式,(struct tm)tmp是指向tm的時間。
×××注4:UTC,指標准時間。簡單的講,就是0時區的時間標准。

3.1 asctime函數

將時間和日期以字符串格式表示。
asctime()將參數time ptr所指的tm結構中的信息轉換成真實世界所使用的時間日期表示方法,然后將結果以字符串形態返回。此函數已經由時區轉換成當地時間,字符串格式為:“Wed Jun 30 21:49:08 1993\n”

time_t timep;
time (&timep);
printf(“%s”,asctime(gmtime(&timep)));

打印出來的效果如下,打印出來的是格林威治時間:

Tue Mar 6 08:47:11 2018

3.2 ctime函數

將時間和日期以字符串格式進行表示。
該函數會將time_t類型的數據轉換成真是世界所使用的時鍾,結果將以字符串形態返回。

time_t timep;
time (&timep);
printf(“%s”,asctime(gmtime(&timep)));

得到的結果是本地時間:

Tue Mar 6 16:55:23 2018

3.3 gettimeofday函數

取得目前的時間
用C語言編寫程序需要獲得當前精確時間(1970年1月1日到現在的時間),或者為執行計時,可以使用gettimeofday()函數。
函數的原型

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

其參數tv是保存獲取時間結果的結構體,參數tz用於保存時區結果:

struct timezone{
int tz_minuteswest;/*格林威治時間往西方的時差*/
int tz_dsttime;/*DST 時間的修正方式*/
}

timezone 參數若不使用則傳入NULL即可。
而結構體timeval的定義為:

struct timeval{
long int tv_sec; // 秒數
long int tv_usec; // 微秒數
}

3.4 gmtime函數

將機器時間轉換成格林威治時間的方法。然后將結果由結構tm返回。
函數的原型為:

struct tm*gmtime(const time_t*timep);

結構tm的定義為

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 日光節約時間的旗標
此函數返回的時間日期未經時區轉換,而是UTC時間。

3.5 localtime函數

取得當地時間和日期。該函數的返回結果也是由tm結構體返回。該函數的參數與返回值與gmtime函數不一樣的地方就是該函數返回的是當地時間。

3.6 mktime函數

將時間結構數據轉換成經過的秒數,mktime()用來將參數timeptr所指的tm結構數據轉換成從公元1970年1月1日0時0分0 秒算起至今的UTC時間所經過的秒數。
函數原型:

time_t mktime(strcut tm * timeptr);

基本的使用效果:

time_t timep;
strcut tm *p;
time(&timep);
printf(“time() : %d \n”,timep);
p=localtime(&timep);
timep = mktime(p);
printf(“time()->localtime()->mktime():%d\n”,timep);

簡單的說,該函數的作用就是用來將strcut tm結構體轉換成timep類型的數據。

3.7 settimeofday函數

設置系統時鍾

 int settimeofday ( const struct timeval *tv,const struct timezone *tz);

settimeofday()會把目前時間設成由tv所指的結構信息,當地時區信息則設成tz所指的結構。詳細的說明請參考gettimeofday()。注意,只有root權限才能使用此函數修改時間。

3.8 time函數

取得目前的時間,此函數會返回從公元1970年1月1日的UTC時間從0時0分0秒算起到現在所經過的秒數。如果t 並非空指針的話,此函數也會將返回值存到t指針所指的內存。
函數原型:

int seconds= time((time_t*)NULL);

4.總結

本次實驗主要分析有關c語言時鍾編程的函數,為后面寫rtc函數打下基礎。


免責聲明!

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



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