获取任何日期的DST信息

时间:2012-09-10 13:57:47

标签: c++ dst

我写了一个为任何日期提供夏令时信息的功能。但它仅适用于当地时区。

  • 有没有办法让它变得普及?
  • 它是否正确或是否有任何我没想过的陷阱?

使用夏令时信息我的意思是:

  • DST已关闭
  • DST已开启
  • 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后的正确结果?
  • 有没有陷阱,我没想过?

0 个答案:

没有答案