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)。

  • 如何使其通用(使用_putenvand后的正确结果_tzset
  • 有没有我没有想到的陷阱?
4

0 回答 0