任意の日付の夏時間情報を提供する関数を作成しました。ただし、ローカル タイム ゾーンでのみ機能します。
- それを普遍的にする方法はありますか?
- それはまったく正しいですか、それとも私が考えていなかった落とし穴がありますか?
夏時間情報とは、次のことを意味します。
- 夏時間はオフです
- 夏時間はオンです
- 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
?- 私が思いもよらなかった落とし穴はありますか?