2014-11-07 148 views
1

給定除當地時區以外的特定時區(例如America/Los_Angeles),如何找到此時區的當前GMT偏移?目的是讓這項工作與DST變化有關。也就是說,洛杉磯的GMT偏移爲-8,在夏令時調整爲-7。獲取特定時區的當前GMT偏移

一些other answers建議操作影響像localtime什麼樣的回報功能TZ環境變量,但我想一個解決方案,不惹環境變量(即非重入爲例)。

似乎所有這些信息都可以在/usr/share/zoneinfo上通過zdump得到,但是我怎麼從C++中得到這個信息並不明顯。

回答

2

我發現了一個使用Boost的解決方案,但它似乎有點迂迴。它使用以下步驟:

  • 加載一個time zone database它可以轉換一個時區名稱,其中包含有關DST何時開始和結束的信息。這是一個幾百行的CSV文件,很容易獲得。
  • 同時使用GMT和特定時間段獲取當前時間,通過查找所述數據庫
  • 取兩個時間之間的差異來獲得GMT偏移

這可能與樣本程序更清晰:

#include <iostream> 
#include <boost/date_time/local_time/local_time.hpp> 

int main(int argc, char* argv[]) { 
    if (argc != 2) { 
      std::cerr << "Usage: program tz_name\n"; 
      return 1; 
    } 

    // Load time zone database 
    boost::local_time::tz_database tz_db; 
    tz_db.load_from_file("date_time_zonespec.csv"); 

    // Current time 
    auto t = boost::posix_time::second_clock::local_time(); 

    // Get the time for GMT; we'll use this to compare against other time zones 
    boost::local_time::time_zone_ptr gmt_tzp{new boost::local_time::posix_time_zone("GMT")}; 
    boost::local_time::local_date_time gmt{t, gmt_tzp}; 

    // Get time for specific time zone 
    boost::local_time::local_date_time local{t, tz_db.time_zone_from_region(argv[1])}; 

    // Calculate difference between local time and GMT time 
    auto difference = local.local_time() - gmt.local_time(); 

    // Print some information 
    auto offset_minutes = difference.total_seconds()/60; 
    std::cout << "Zone " << local.zone()->std_zone_name() << " GMT offset minutes " << offset_minutes << "\n"; 
    return 0; 
} 

樣品的使用和輸出:

$ ./a.out "America/Los_Angeles" 
Zone Pacific Standard Time GMT offset minutes -480 
$ ./a.out "Asia/Dubai" 
Zone GST GMT offset minutes 240 
$ ./a.out "Australia/Sydney" 
Zone EST GMT offset minutes 660 
+0

這裏的問題是[Boost的時區文件](https://github.com/boostorg/date_time/blob/master/data/date_time_zonespec.csv)嚴重過時。當它*是*準確時,它只對*當前*區域規則準確。它像POSIX區域一樣平坦。 [實時時區數據庫](http://www.iana.org/time-zones)包括時區規則隨時間變化的豐富歷史。 – 2014-11-07 16:50:54

1

對一個老問題的新信息:

有一個新的開源timezone library完全解析當地的IANA database的副本(包括所有的歷史數據,甚至閏秒)。 C++ 11或C++ 14編譯器是必需的。您可以隨時使用它來查找任何時區的詳細信息。上面的鏈接中包含有關該庫的詳細信息。

一個例子程序是:

#include "tz.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace date; 
    using namespace std::chrono; 
    auto zone = locate_zone("America/Los_Angeles"); 
    auto tp = system_clock::now(); 
    auto info = zone->get_info(tp); 
    std::cout << "Information for " << zone->name() << " at " << tp << " UTC is:\n" 
       << info << '\n'; 

    tp = sys_days{nov/7/2014} + 53min; 
    info = zone->get_info(tp); 
    std::cout << "Information for " << zone->name() << " at " << tp << " UTC is:\n" 
       << info << '\n'; 
} 

這只是對我輸出:

Information for America/Los_Angeles at 2015-07-18 19:34:30.112820 UTC is: 
2015-03-08 10:00:00 
2015-11-01 09:00:00 
-07:00:00 
01:00 
PDT 

Information for America/Los_Angeles at 2014-11-07 00:53:00.000000 UTC is: 
2014-11-02 09:00:00 
2015-03-08 10:00:00 
-08:00:00 
00:00 
PST 

該輸出解釋如下:

  • 的一天,我在回答這個問題,「America/Los_Angeles」的UTC偏移量爲-7小時,時區縮寫爲PDT。這距離該地區的「標準時間」1小時。此偏移和縮寫至少在UTC時間點的這個範圍內有效:[2015-03-08 10:00:00,2015-11-01 09:00:00]。

  • 問這個問題的那一天,「America/Los_Angeles」的UTC偏移量是-8小時,時區的縮寫是PST。這並沒有抵消該地區的「標準時間」。此偏移量和縮寫至少在UTC時間點的這個範圍內有效:[2014-11-02 09:00:00,2015-03-08 10:00:00)。

這是一個github project,拉請求,以幫助它移植到儘可能多的C++ 11月14日平臺,實際是受歡迎的。