【问题标题】:Detect daylight saving time algorithm检测夏令时算法
【发布时间】:2016-06-18 07:24:06
【问题描述】:

我写了一个类 Instant 管理与时区相关的日期和时间以及一些夏令时算法(EuropeUSA)。 到现在为止,我让类的用户使用Europe 作为默认值来指定 DST 算法。但是现在我想自动检测它的默认值。

这是我的第一个实现。它似乎适用于我的 Windows 7 工作站(编译器:intel 14.0)(我必须澄清一下列表),但它不适用于 Linux openSUSE(编译器:gcc 4.8.3),因为tz.tz_dsttime 始终为 0。

typedef enum {
    DST_ALGO_NONE   = 0,
    DST_ALGO_EUROPE = 1,
    DST_ALGO_USA    = 2
} TimeZoneType;

TimeZoneType auto_detect_dst_algorithm()
{
#   ifdef WIN32
        TIME_ZONE_INFORMATION tz;
        GetTimeZoneInformation(&tz);
        std::wstring tz_wstr = tz.DaylightName;
        std::string tz_str(tz_wstr.begin(), tz_wstr.end());
        if(   tz_str.find("Romance") != std::string::npos
           || tz_str.find("RST") != std::string::npos
           || tz_str.find("Central Europe") != std::string::npos
           || tz_str.find("CEST") != std::string::npos
           || tz_str.find("Middle Europe") != std::string::npos
           || tz_str.find("MET") != std::string::npos
           || tz_str.find("Western Europe") != std::string::npos
           || tz_str.find("WET") != std::string::npos )
        {
            return DST_ALGO_EUROPE;
        }
        else if(   tz_str.find("Pacific") != std::string::npos
                || tz_str.find("PDT") != std::string::npos )
        {
            return DST_ALGO_USA;
        }
        else
        {
            return DST_ALGO_NONE;
        }
#   else
        struct timeval tv;
        struct timezone tz;
        gettimeofday(&tv, &tz);
        if(tz.tz_dsttime == 1)
        {
            return DST_ALGO_USA;
        }
        else if(tz.tz_dsttime == 3 || tz.tz_dsttime == 4)
        {
            return DST_ALGO_EUROPE;
        }
        else
        {
            return DST_ALGO_NONE;
        }
#   endif
}

这样做的好方法是什么?

【问题讨论】:

  • “有什么好的方法吗?”使用图书馆!!!!!!说真的时区不是你想自己做的事情。
  • 是的,我想要。那问题呢?
  • 给出一个理智的理由。
  • 既然已经存在很多库,为什么还要创建新库?
  • 我写这个库是因为我需要一些在其他库中没有的特定打印功能。它正在工作。我只想找到如何正确初始化它。有人可以提供帮助,或者我需要就我的工作召开会议?...

标签: c++ dst


【解决方案1】:

来自the gettimeofday man page

在 Linux 上,使用 glibc,settimeofday()gettimeofday()从未使用过 struct timezone 的 tz_dsttime 字段的设置。因此,以下内容仅具有历史意义。

在旧系统上,tz_dsttime 字段包含一个符号常量...

...当然,夏令时生效的时间段不能通过简单的算法给出,每个国家一个;事实上,这一时期是由不可预测的政治决定决定的。 所以这种表示时区的方法已经被放弃了

原问题中的 cmets 是正确的。您不应该尝试自己实现这一点,尤其是使用废弃的 API。

即使在示例代码的 Windows 部分中,您也会对可能在 DaylightName 字段中找到的内容做出很多假设。您确实意识到时区比您要测试的时区多得多,对吧?此外,在用户选择了英语以外的主要语言的系统上,这些字符串的显示方式会完全不同。

C++ 有很多不错的时区库。任何有价值的东西都将使用the IANA tz database 作为其来源。我会好好看看the best practices FAQthe timezone tag wiki。特别是,FAQ 建议使用 CCTZICUTZ,并警告不要将 Boost 用于此功能。

【讨论】:

    猜你喜欢
    • 2011-09-03
    • 2013-11-22
    • 2014-08-11
    • 2014-04-25
    • 2013-11-24
    • 2012-10-16
    • 2010-09-09
    • 2017-07-11
    相关资源
    最近更新 更多