获取特定时区的当前GMT偏移量

时间:2014-11-07 00:53:19

标签: c++ timezone

给定除本地时区以外的特定时区(例如America/Los_Angeles),如何找到此时区的当前GMT偏移量?目的是让这项工作与DST的变化有关。也就是说,洛杉矶的GMT偏移为-8,在夏令时调整为-7。

有些other answers建议操纵TZ环境变量,这会影响像localtime这样的函数返回,但我想要一个不会混淆环境变量的解决方案(例如不可重入) )。

所有这些信息似乎都可以通过/usr/share/zoneinfozdump上获得,但我不知道如何从C ++中获取此信息。

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

您可以考虑使用ICU的一种方法。它包含(除其他外)在时区之间转换的函数。请参阅the documentation for the TimeZone class

例如,您可以创建时区对象:

TimeZone *tz = TimeZone::createTimeZone("America/Los_Angeles");

然后,您可以使用getOffset等方法。

另请参阅ICU Time Zone User Guidethis complete example

答案 2 :(得分:1)

旧问题的新信息:

有一个新的开源timezone library完全解析IANA database的本地副本(包括所有历史数据甚至闰秒)。需要C ++ 11或C ++ 14编译器。您可以随时使用它来查找有关任何时区的详细信息。有关此库的详细信息,请参见上面的链接。

一个示例程序是:

override func viewDidAppear(animated: Bool) 
{
    if(!PFUser.currentUser())
    {
        var loginAlert:UIAlertController = UIAlertController(title: "Please Sign up or Log In", message: "Publish your Quote Today", preferredStyle: UIAlertControllerStyle.Alert)

        loginAlert.addTextFieldWithConfigurationHandler({
            textfield in
            textfield.placeholder = "Author or Publisher"
        })

        loginAlert.addTextFieldWithConfigurationHandler({
            textfield in
            textfield.placeholder = "Your Lock"
            textfield.secureTextEntry = true
        })

哪个只为我输出:

#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';
}

此输出解释如下:

  • 我回答这个问题的那天,“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平台。