10

時間領域で遊ぶようになった私たちのほとんどが知っていると確信している楽しい事実-有効に見えるが実際には存在しない日付/時刻があります。たとえば、夏時間の切り替え時間の午前2時30分です。

C++ (標準または Windows) で、特定の日付/時刻が特定のタイム ゾーン仕様で有効かどうかを判断する方法はありますか?

4

3 に答える 3

1

Windows 固有の関数を使用すると、 を呼び出してから、関連するタイム ゾーンを指定してを呼び出すことができます。 TzSpecificLocalTimeToSystemTime() SystemTimeToTzSpecificLocalTime()

完了時に、2 つが異なる場合、無効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 に設定します。これは、DST かどうかがわからないことを示します。
    • mktime() を使用して、「struct tm」を time_t に変換します。
    • localtime() を使用して、time_t を "struct tm" に変換します。
    • 結果の「struct tm」を最初の「struct tm」と比較し、tm_isdst フィールドを無視します (または、DST にいるかどうかを確認するために使用します)。
于 2016-04-08T07:09:50.780 に答える