2012-05-23 92 views
4

我試圖用strftime功能當前UTC時間進行編碼轉換爲字符串:得到使用的strftime()UTC時間戳

time_t now; 
struct tm nowLocal; 
struct tm nowUtc; 

now = time(NULL); 
localtime_r(&now, &nowLocal); 
gmtime_r(&now, &nowUtc); 

到目前爲止好:nowLocal包含當前時間在我的時區(CET),nowUtc包含UTC時間,不同的是究竟根據tm_gmtoff值:

nowLocal: {tm_sec = 28, tm_min = 27, tm_hour = 13, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"} 

nowUtc: {tm_sec = 28, tm_min = 27, tm_hour = 11, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 0, tm_gmtoff = 0, tm_zone = 0x3e9907 "GMT"} 

然後我叫strftime()"%s"格式得到紀元以來的秒數:

char tsFromLocal[32]; 
char tsFromUtc[32]; 

strftime(tsFromLocal, sizeof(tsFromLocal), "%s", &nowLocal); 
strftime(tsFromUtc, sizeof(tsFromUtc), "%s", &nowUtc); 

結果對我來說似乎很奇怪。我期望從strftime()調用中得到完全相同的字符串,因爲%s格式描述爲:

自紀元以來的秒數,即從1970-01-01 00:00:00 UTC開始的秒數。除非有閏秒支持,否則閏秒不計算在內。

但是我有兩個不同的值:

tsFromLocal:"1337772448" 

tsFromUtc: "1337768848" 

而且差異不tm_gmtoff),但。任何人都能解釋這種行爲嗎或者它是一個錯誤?

我這樣做的原因是我需要通過網絡傳輸時間值,並將其與目標機器上可能處於不同時區的當前時間進行比較。在目標機器,我想:

struct tm restoredUtc; 
time_t restored; 

strptime(tsFromUtc, "%s", &restoredUtc); 
restored = timegm(&restoredUtc); 

但我得到:

restoredUtc:{tm_sec = 28, tm_min = 27, tm_hour = 12, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"} 

所以strptime()根據反正當前時區設置tm_zone。但是,即使我會使用的timelocal()代替timegm()我不會得到正確的值,因爲它應該是11時27分28秒CEST,而不是12點27分28秒CEST。這個錯誤是否與strftime()的不同結果有關?

對此後續部分的任何評論?

+2

據我所知,'strftime()'將傳遞的時間結構解釋爲LOCAL TIME。由於原始'nowLocal'結構具有'tm_isdst = 1'(由前一次調用localtime_r()設置),因此您得到1小時的差異。如果在調用strftime之前將此字段設置爲0,則可能會得到您期望的2小時差異。 – Claudix

+0

考慮到你從time()的結果中獲得了時間,你可以將它與'strftime()'返回的結果進行比較,以確定哪個答案是正確的(如果有的話) 。我的猜測是當地時間是正確的,UTC是錯誤的。你是否可以讓'strftime()'工作,因爲你不想將TZ變量設置爲'UTC0',然後調用'tzset()'就可以討論了。 –

回答

2

你可能是最好的只是使用格林威治標準時間,因爲有gmtime_r總是會給你所有地方相同的答案。如果一臺機器想要在當地時間顯示,可以稍後完成,但堅持一個時區進行存儲和網絡傳輸是一個好主意,並且GMT值很容易獲得。

0

我懷疑評論是正確的:strftime()將時間解釋爲當地時間。請注意,tm_gmtoff不是一個標準化的字段;我想知道strftime()是否在看它。但我找不到任何具體的證實這一點。

但是,回答問題的第二部分,爲什麼不直接將time(NULL)的結果通過網絡傳輸?或者,如果您已經有時間以struct tm的形式,請使用mktime()轉換爲time_t,然後將其轉移? printf("%lu", (unsigned long) time)比試圖使用strftime("%s")要簡單得多,而C99或POSIX沒有對其進行標準化。

0

Q1:任何人都可以解釋這種行爲嗎?或者它是一個錯誤?

是的,這是一個錯誤,在tsFromLocal:"1337772448"!= tsFromUtc: "1337768848"。但是該錯誤位於tsFromUtc。他們應該是相同的,他們都應該是1337772448.

1337772448%(24 * 60 * 60) - > 41248是一天的UTC秒或11:27:28這與您的nowUtc結構匹配,並且是你認爲它的時間(UTC)

Q2:...這個錯誤與strftime()的不同結果有關嗎?

我同意使用time_t作爲網絡通信的整數。

是的,它是這樣的。

如果您想進一步瞭解這篇文章:請考慮在time(&now)之後張貼now的數字值,並明確指出您當時的預期時間。