2012-09-21 47 views
1

這一個現在一直困擾我一分鐘。我正在編寫一個用C++編寫的程序,我需要能夠在兩個不同的服務器之間發送ISO8601編碼的時間。這裏主要的堅持者似乎是Windows。將UTC tm *轉換爲本地化tm *的跨平臺方式?

到目前爲止,我已經從NetBSD移植了strptime(),以便輕鬆讀取日期/時間字符串並將其變爲tm*。然而,當我把它變成一個本地化的tm*時,我完全被難住了,於是我可以使用strftime()在本地時區顯示這個時間給用戶。一種天真的做法是簡單地取localtime(time(0))gmtime(time(0))之間的差異,但這對於涉及夏令時的任意日期將不一致。

到目前爲止,我採用的方法是僅使用POSIX日期和時間函數,並在必要時編寫Windows填充程序(如果需要,可以在strptime()timegm()之間完成)。我寧願繼續這樣做,但簡單的事實是,Windows中的tm*結構缺少一些Linux和OSX所做的字段,所以我可能沒有選擇,只能編寫由#if WIN32保護的非可移植代碼。我也非常喜歡不必爲此而提振。

+0

即使你不想使用升壓,我還是會建議你使用boost是否能解決問題? – villintehaspam

回答

1

給出一個struct tm *utc_tm您可以用把它變成一個time_t utc(不可移植)timegm,使用localtime然後把它轉換成一個struct tm *local_tm

time_t utc = timegm(utc_tm); 
struct tm local_tm; 
localtime_r(&utc, &local_tm); 

從我可以告訴的timegm最簡單的實現方式包括做使用月份表和閏年計算來轉換自己。另外,如果您strptime填寫tm_yday正確,您可以從https://stackoverflow.com/a/9076848/567292用公式:

tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 + 
    (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 - 
    ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400 
+0

您的回答起初讓我感到困惑,因爲這是我丟棄的方法;我錯誤地認爲time_t在Windows上隨時區變化。然而,仔細看MSDN,證實了你的方法的正確性。謝謝! – AlexMax