2010-11-12 52 views
4

我正在用C++編寫一個Linux(Ubuntu和Debian Lenny)應用程序。距離UTC - Linux上的LocalTime

現在我需要知道UTC和當前設定的系統時間之間的距離/偏移量。由於我需要轉換記錄的數據,因此我需要根據過去的日期計算距離(可能與當天有不同的DST設置)。

任何人都知道如何做到這一點?

編輯:讀第一個答案我想我被誤解了:我不想比較日期/時間。我有我想從UTC轉換到當地時間的日期/時間值。

+2

一個問題是基於不同的夏令時法律 – warren 2010-11-12 21:16:55

回答

3

與約會的準備tm結構:

struct tm date; 
memset(&date,0,sizeof(date)); 
date.tm_year = year - 1900; 
date.tm_mon = month - 1; 
date.tm_mday = day; 
date.tm_hour = hour; 
date.tm_min = minute; 
date.tm_sec = second; 
date.tm_isdst = -1; // VERY IMPORTANT 

mktime(&date); /// fill rest of fields 

,然後看看tm_gmtoff

printf("%d\n",date.tm_gmtoff); 

這是距UTC的距離。

現在,這是Linux和BSD特有的,它不會在其他系統上工作,並且這與DST相關的工作 。

閱讀man mktime以獲取更多信息。並用正確的值填充struct tm

P.S .:從UTC轉換到本地並返回?

time_t posix_time = timegm(&UTC_Filled_struct_tm); // Linux specific line 
localtime_r(&posix_time,&local_Filled_struct_tm); 

地方爲UTC

time_t posix_time = mktime(&local_Filled_struct_tm); 
gmtime_r(&posix_time,&UTC_Filled_struct_tm); 
+0

這爲我做的本地時間與UTC的方差,謝謝! – 2010-11-15 10:48:28

0

確保所有時間都轉換爲UTC(例如,請參閱mktime())。然後,您可以使用difftime()或timeval_subtract例如函數從相同的鏈接,這取決於結構的時間存儲在

2

我想你可以使用Boost.DateTime或ICU受益。

至於Boost.DateTime TT可能是這樣的:

1)你準備用時區信息Boost.Datetime一個數據庫,並創建一個時區。因爲他們持有約DST

tz_database tz_db; 
tz_db.load_from_file("./date_time_zonespec.csv"); 
time_zone_ptr nyc = tz_db.time_zone_from_region("America/New_York"); // or other timezone 


信息,或者只是創建這樣一個時區時區是很重要的。

std::string kaliningrad_string = "EET+02:00:00EEST+01:00:00,M3.5.0/02:00:00,M10.5.0/03:00:00"; 
boost::local_time::time_zone_ptr kaliningrad_tzone_posix(new boost::local_time::posix_time_zone(kaliningrad_string)); 
std::string vladivostok_string = "VLAT+10:00:00VLAST+01:00:00,M3.5.0/02:00:00,M10.5.0/03:00:00"; 
boost::local_time::time_zone_ptr vladivostok_tzone_posix(new boost::local_time::posix_time_zone(vladivostok_string)); 

使用時區的字符串規範創建時區看起來更加困難,但你可以利用它,如果你不能找到date_time_zonespec.csv特定的時區。 例如薩馬拉曾經在2010年3月之前是UTC + 4,現在是UTC + 3。 date_time_zonespec.csv沒有更改歷史記錄,所以在這種情況下,需要在字符串規範外創建一個時區。不過我記得,ICU似乎與這種歷史ICU TimeZone Classes的時區:經常

時區數據的變化 應對 世界各國政府改變他們的地方性法規和 他們應用領域。在ICU 時區數據爲每個 釋放,留 最新可升級到最新的 ICU釋放,這也 提供bug修復,代碼改進 和附加功能的最簡單的方法更新。


3)讓你需要一個本地時間,例如

local_date_time tmp(boost::gregorian::date(2010, 3, 28), boost::posix_time::time_duration(1,59,0),nyc, boost::local_time::local_date_time::EXCEPTION_ON_ERROR); 

4),然後使用功能utc_timelocal_time
有是頁面上的例子計算的區別:

ptime pt(date(2004,Nov,5), 
     hours(10)); 
time_zone_ptr zone(new posix_time_zone("MST-07")); 
local_date_time az(pt, zone); 
az.utc_time(); // 10am 2004-Nov-5 
az.local_time(); // 3am 2004-Nov-5 


5)另一個例子。本地時間是相同的,但UTC是不同的,你可能有這樣

local_date_time tmp(boost::gregorian::date(2010, 3, 28), boost::posix_time::time_duration(1,59,0),kaliningrad_tzone_posix, boost::local_time::local_date_time::EXCEPTION_ON_ERROR); 
std::cout << "As is: " << tmp << ", UTC: " << tmp.utc_time() << std::endl; 

local_date_time tmp(boost::gregorian::date(2010, 3, 28), boost::posix_time::time_duration(1,59,0),vladivostok_tzone_posix, boost::local_time::local_date_time::EXCEPTION_ON_ERROR); 
std::cout << "As is: " << tmp << ", UTC: " << tmp.utc_time() << std::endl;