有没有办法确定日期/时间是否不存在



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

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

使用Windows特定的函数,可以调用TzSpecificLocalTimeToSystemTime(),然后调用具有相关时区的SystemTimeToTzSpecificLocalTime()

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

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

使用这个免费的开源库:

#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

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

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

  • 将成员tm_isdst设置为-1。这表示您不知道是否为夏令时。
    • 使用mktime()将"structtm"转换为time_t
    • 使用localtime()将time_t转换回"structtm"
    • 将生成的"structtm"与初始的"struct tm"进行比较,忽略tm_isdst字段(或使用它来查看是否处于DST)

相关内容

  • 没有找到相关文章

最新更新