1

任意の日付の夏時間情報を提供する関数を作成しました。ただし、ローカル タイム ゾーンでのみ機能します。

  • それを普遍的にする方法はありますか?
  • それはまったく正しいですか、それとも私が考えていなかった落とし穴がありますか?

夏時間情報とは、次のことを意味します。

  • 夏時間はオフです
  • 夏時間はオンです
  • DST がオフからオンに変わる
  • DST がオンからオフに変わる

機能は次のとおりです。

enum DST { DST_OFF, DST_ON, DST_OFFTOON, DST_ONTOOFF };

DST getdstinfo(int year, int month, int day) {
    tm a = {};
    a.tm_isdst = -1;
    a.tm_mday = day;
    a.tm_mon  = month - 1;
    a.tm_year = year - 1900;
    tm b = a;
    a.tm_hour = 23;
    a.tm_min = 59;
    mktime(&a);
    mktime(&b);

    if      (a.tm_isdst  && b.tm_isdst)  return DST_ON;
    else if (!a.tm_isdst && !b.tm_isdst) return DST_OFF;
    else if (a.tm_isdst  && !b.tm_isdst) return DST_OFFTOON;
    else                                 return DST_ONTOOFF;
}

タイムゾーンを明示的に設定しないと、この関数は Windows (Visual Studio 2010) のテストケースで動作するようです。テストケースは次のとおりです。

#include <cstdlib>
#include <cstdio>
#include <ctime>

const char* WHAT[] = {
    "noDST", "DST", "switch noDST to DST", "switch DST to noDST"
};

int main() {
    const int DAY[][4] = {
        { 2012,  3, 24, DST_OFF },
        { 2012,  3, 25, DST_OFFTOON },
        { 2012,  3, 26, DST_ON },
        { 2012,  5, 22, DST_ON },
        { 2012, 10, 27, DST_ON },
        { 2012, 10, 28, DST_ONTOOFF },
        { 2012, 10, 29, DST_OFF },
        { 2013,  3, 30, DST_OFF },
        { 2013,  3, 31, DST_OFFTOON },
        { 2013,  4,  1, DST_ON },
        { 2013, 10, 26, DST_ON },
        { 2013, 10, 27, DST_ONTOOFF },
        { 2013, 10, 28, DST_OFF },
    };
    const int DAYSZ = sizeof(DAY) / sizeof (*DAY);

    //_putenv("TZ=Europe/Berlin");
    //_tzset();

    for (int i = 0; i < DAYSZ; i++) {
        printf("%04d.%02d.%02d (%-20s) = %s\n",
            DAY[i][0], DAY[i][1], DAY[i][2],
            WHAT[DAY[i][3]],
            WHAT[getdstinfo(DAY[i][0], DAY[i][1], DAY[i][2])]);
    }
    return 0;   
}

結果は次のとおりです。

2012.03.24 (noDST               ) = noDST
2012.03.25 (switch noDST to DST ) = switch noDST to DST
2012.03.26 (DST                 ) = DST
2012.05.22 (DST                 ) = DST
2012.10.27 (DST                 ) = DST
2012.10.28 (switch DST to noDST ) = switch DST to noDST
2012.10.29 (noDST               ) = noDST
2013.03.30 (noDST               ) = noDST
2013.03.31 (switch noDST to DST ) = switch noDST to DST
2013.04.01 (DST                 ) = DST
2013.10.26 (DST                 ) = DST
2013.10.27 (switch DST to noDST ) = switch DST to noDST
2013.10.28 (noDST               ) = noDST

しかし、行のコメントを外す_putenvと、すべてのテストケース_tzsetの結果が得られDSTます (おそらく、現在 DST があるためです)。

  • _putenvそれを普遍的にする方法(およびを使用した後の正しい結果は_tzset
  • 私が思いもよらなかった落とし穴はありますか?
4

0 に答える 0