10

有趣的事实是,我相信我们中的大多数玩时间领域的人都知道——有些日期/时间可能看起来有效但实际上并不存在,例如夏令时切换时间的凌晨 2:30。

C++(标准或Windows)中有没有办法确定给定日期/时间在给定时区规范中是否有效?

4

3 回答 3

1

使用特定于 Windows 的函数,您可以先调用 to, TzSpecificLocalTimeToSystemTime()然后再使用相关时区调用 to 。 SystemTimeToTzSpecificLocalTime()

完成后,如果两者不同,则您有一个无效时间,因为TzSpecificLocalTimeToSystemTime将无效时间转换为“实时”时间。

bool IsValidTime(TIME_ZONE_INFORMATION tz, SYSTEMTIME st)
{
    SYSTEMTIME utcSystemTime, st2;
    TzSpecificLocalTimeToSystemTime(&tz, &st, &utcSystemTime);
    SystemTimeToTzSpecificLocalTime(&tz, &utcSystemTime, &st2);

    return (st != st2);
}
于 2016-04-11T00:40:18.767 回答
1

使用这个免费的开源库

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

int
main()
{
    using namespace date;
    using namespace std::chrono_literals;
    try
    {
        auto zone = locate_zone("America/New_York");
        zone->to_sys(local_days{mar/13/2016} + 2h + 30min);
    }
    catch (const std::exception& e)
    {
        std::cout << e.what() << '\n';
    }
}

这个程序的输出是:

2016-03-13 02:30 is in a gap between
2016-03-13 02:00:00 EST and
2016-03-13 03:00:00 EDT which are both equivalent to
2016-03-13 07:00:00 UTC

简而言之,该程序尝试使用时区“America/New_York”将 2016-03-13 02:30:00 的区域设置日期/时间转换为 UTC。由于本地时间不存在,翻译会引发异常。如果本地时间不明确,例如从夏令时设置本地时钟时,也会引发异常(带有不同的错误消息)。

如果需要,该库还提供了避免这些异常的语法。

这适用于 VS-2013、VS-2015、clang 和 gcc。它需要 C++11、C++14 或 C++1z。

上面的链接指向文档。这是github存储库:

https://github.com/HowardHinnant/date

于 2016-04-10T15:08:33.217 回答
0

time_t 格式是一个整数值(自 1970 年 1 月 1 日 00:00 UTC 以来的秒数),因此 time_t 的每个可能值都存在(当然在使用的整数类型的范围内)。

另一方面,并​​非所有可能的“struct tm”值(其中您有日、月、年、小时、分钟和秒的成员)都存在(这可能就是您的意思)。要检查“struct tm”是否存在,您必须执行以下操作:

  • 将成员 tm_isdst 设置为 -1。这表明你不知道它是否是夏令时。
    • 使用 mktime() 将“struct tm”转换为 time_t。
    • 使用 localtime() 将 time_t 转换回“struct tm”。
    • 将生成的“struct tm”与初始的“struct tm”进行比较,忽略 tm_isdst 字段(或使用它来查看您是否在 DST 中)。
于 2016-04-08T07:09:50.780 回答