時間和日期
通常能確定時間和日期對乙個程式來說是非常有用的。程式可能希望記錄它執行的時間,或者可能需要在某些時候改變它的執行方式。例如,乙個遊戲可能拒絕在工作時間執行,或者乙個定時備份程式可能想等到每天的凌晨才開始乙個自動備份。
所有的unix系統都使用同乙個時間和日期的 起點:格林尼治時間(gmt)2023年1月1日午夜(0點)。這是「unix紀元的起點」,linux也不例外。linux系統中所有的時間都以從那時 起經過的秒數來衡量。這和ms-dos處理時間的方法類似,只是ms-dos紀元始於2023年。其他系統使用其他的紀元起始時間。
時間通過乙個預定義的型別time_t來處理。這是乙個大到能夠容納以秒計算的日期和時間的整數型別。在linux系統中,它是乙個長整型,與處理時間值的函式一起定義在標頭檔案time.h中。
絕不要想當然地以為,時間就是32位的。在使用32位time_t型別的unix和linux系統中,時間將在2023年迴繞。那時,我們希望系統都開始使用大於32位的time_t型別。
你可以通過呼叫time函式得到底層的時間值,它返回的是從紀元開始至今的秒數。如果tloc不是乙個空指標,time函式還會把返回值寫入tloc指標指向的位置。
實驗:time函式
下面這個簡單的程式envtime.c演示了time函式的用法:
執行這個程式,它會在20秒時間內每兩秒鐘列印一次底層的時間值。
實驗解析
這個程式用乙個空指標引數呼叫time函式,返回以秒數計算的時間和日期。程式休眠兩秒後再重複呼叫time函式,總共呼叫10次。
以從2023年開始計算的秒數來表示時間和日期,對測算某些事情持續的時間是很有用 的。我們可以把它考慮為只是簡單地把兩次呼叫time得到的值相減就行了。然而iso/ansi c標準委員會經過深思熟慮,並沒有規定用time_t型別來測量任意時間之間的秒數,他們發明了乙個函式difftime,該函式用來計算兩個 time_t值之間的秒數並以double型別返回它。
difftime函式計算兩個時間值之間的差,並將time1-time2的值作為浮點數返回。對linux來說,time函式的返回值是秒數,可以對它進行處理,但考慮到最大限度的增加可移植性,則最好使用difftime。
為了提供(對人類)更有意義的時間和日期,我們需要把時間值轉換為可讀的時間和日期。有一些標準函式可以幫我們做到這一點。
gmtime函式把底層時間值分解為乙個結構,該結構包含一些常用的字段。
tm結構定義為至少包含表4-2所示的成員。
表 4-2
tm成員
說 明
int tm_sec
秒,0~61
(續)tm成員
說 明
int tm_min
分,0~59
int tm_hour
小時,0~23
int tm_mday
月份中的日期,1~31
int tm_mon
月份,0~11(一月份為0)
int tm_year
從2023年開始計算的年份
int tm_wday
星期幾,0~6(週日為0)
int tm_yday
年份中的日期,0~365
int tm_isdst
是否夏令時
tm_sec的範圍允許臨時閏秒或雙閏秒。
實驗:gmtime函式
下面這個程式gmtime.c利用tm結構和gmtime函式列印出當前時間和日期:
執行這個程式,我們得到含義明顯的時間和日期:
實驗解析
程式呼叫time函式得到底層的時間值,然後呼叫gmtime將該值轉換為乙個包含更 有用的時間和日期值的結構。程式用printf將這些資訊列印出來。嚴格來說,不應該用這種方法列印原始時間值,因為我們並不能保證它在所有系統上都是 long型別的值。我們在gmtime程式後立即執行date命令,以比較它們的輸出。
不過,這兒有個小問題。如果你在格林尼治標準時間(gmt)之外的時區執行這個程式, 或者如果你所在的地方採用了夏令時,你會發現時間(可能還有日期)是不對的。因為gmtime按gmt返回時間(現在gmt被稱為世界標準時間,或 utc)。linux和unix這樣做是為了同步全球各地的所有程式和系統。不同時區同一時刻建立的檔案就會有相同的建立時間。要看當地時間,我們需要使 用localtime函式。
localtime函式和gmtime一樣,除了它返回的結構中包含的值已根據當地時區和是否採用夏令時做了調整。如果你把上面程式中gmtime換成localtime再編譯執行一次,你就會看到正確的時間和日期了。
要把已分解出來的tm結構再轉換為原始的time_t時間值,可以使用mktime函式:
如果tm結構不能表示為time_t值,mktime將返回-1。
為了得到更「友好」的時間和日期表示,像date命令輸出的那樣,我們可以使用asctime函式和ctime函式:
asctime函式返回乙個字串,表示由tm結構timeptr所給出的時間和日期。這個返回的字串有類似下面的格式:
它總是這種長度為26個字元的固定格式。ctime函式等效於呼叫
它以原始時間值為引數,並將它轉換為可讀的本地時間。
實驗:ctime函式
我們用下面的**來看看ctime函式的用法。
編譯並執行這個ctime.c程式,輸出如下:
實驗解析
ctime.c程式呼叫time函式得到底層時間值,讓ctime做所有的艱鉅工作,把時間值轉換成可讀的字串,然後列印它。
為了對時間和日期字串的格式有更多控制,linux和現代的類unix系統提供了strftime函式。它很像是乙個針對時間和日期的sprintf函式,工作方式也很類似:
strftime函式格式化timeptr指標指向的tm結構所表示的時間和日期,並 將結果放在字串s中。字串被指定(至少)maxsize個字元。format字串用於控制寫入字串s的字元。與printf一樣,它包含將被傳給 字串的普通字元和用於格式化時間和日期元素的轉換控制符。轉換控制符見表4-3。
表 4-3
轉換控制符
說 明
轉換控制符
說 明
%a
星期幾的縮寫
%s
秒,00~61
%a
星期幾的全稱
%u
星期幾,1~7(周一為1)
%b
月份的縮寫
%u
一年中的第幾周,01~53(週日是一周的第一天)
%b
月份的全稱
%v
一年中的第幾周,01~53(周一是一周的第一天)
%c
日期和時間
%w
星期幾,0~6(週日為0)
%d
月份中的日期,01~31
%x
本地格式的日期
%h
小時,00~23
%x
本地格式的時間
%i
12進製的小時,01~12
%y
年份減去1900
%j
年份中的日期,001~366
%y
年份
%m
年份中的月份,01~12
%z
時區名
%m
分鐘,00~59
%%
字元%
%p
a.m.(上午)或p.m(下午)
因此,date命令輸出的普通日期就相當於strftime格式字串中的:
為了幫助讀取日期,我們可以使用strptime函式,該函式以乙個代表日期和時間的字串為引數,並建立表示同一日期和時間的tm結構:
format字串的構建方式和strftime的format字串完全一樣。 strptime在字串掃瞄方面類似於sscanf函式,也是查詢匹配資料字段,並把它們寫入對應的變數中。只是這裡是根據format字串填充tm 結構的成員。不過,strptime的轉換控制符與strftime的相比,限制要稍微松一些,因為strptime中的星期幾和月份用縮寫和全稱都行, 兩者都匹配strptime中的%a控制符,此外,strftime使用小於10的數字總以0開頭,而strptime則把它看作是可選的。
strptime返回乙個指標,指向轉換過程處理的最後乙個字元後面的那個字元。如果碰到不能轉換的字元,轉換過程就在該點停下來。呼叫程式需要檢查是否已從傳遞的字串中讀入了足夠多的內容,以確保tm結構中寫入了有意義的值。
實驗:strftime函式和strptime函式
請留意下面這個程式中選用的轉換控制符:
編譯並執行這個程式strftime.c,我們得到:
實驗解析
strftime程式通過呼叫time和localtime得到當前的本地時間。然 後,它通過呼叫帶有合適的格式引數的strftime將時間轉換成可讀的格式。為演示strptime的用法,程式構建了乙個包含日期和時間的字串,然 後呼叫strptime將原始時間和日期值分解並列印出來。轉換控制符%r是strptime中對%h:%m的縮寫形式。
注意:要成功地掃瞄日期,strptime需要乙個精確的格式字串。這一點非常重要。一般來說,該函式不會精確掃瞄讀自使用者的日期,除非使用者輸入的格式非常嚴格。
編譯strftime.c時,你可能會看到編譯器有乙個警告資訊。因為gnu庫在預設情況下並未宣告strptime函式。要解決這個問題,在包含time.h標頭檔案的語句之前加上如下一行即可,它的作用是明確請求使用x/open標準的功能:
設定Linux時間和日期
date 三 11月 1215 08 45 cst 2014 date s 11 14 2014 五 11月 1400 00 00 cst 2014 date 五 11月 1400 00 02 cst 2014 date s 8 35 00 五 11月 1408 35 00 cst 2014 等同於...
linux日期同步和時間類
date 顯示當前的時間 基本語法 1 date 功能描述 顯示當前時間 2 date y 功能描述 顯示當前年份 3 date m 功能描述 顯示當前月份 4 date d 功能描述 顯示當前是哪一天 5 date y m d h m s 功能描述 使用特定格式顯示年月日時分秒 手動設定系統時間如...
linux 時間和日期的設定
linux機器上的時間比較複雜,有各式各樣的時鐘和選項等等。機器裡有兩個時鐘,硬體時鐘從根本上講是cmos時鐘,而系統時鐘是由核心維護的。1 更新機器的硬體時間。命令為 hwclock adjust 硬體時鐘通常被設定成全球標準時間 utc 而將時區資訊儲存在 usr share lib timez...