Cのライブラリ。VC++4.2なんていう古いものだが先日問題が発生した。
Cのライブラリの時刻関数であるtimeとlocaltimeで取得した時間が、
4月6日の午前2時台に-1時間されていたという現象が発生。


OSのタイムゾーン設定は間違いなく日本である事の確認と、
以下のサンプルコードで該当時間に現象が発生するのを確認。
その後、この関数をぐるぐる回して2011年迄毎時チェック。
ちなみにtzsetはやってもやらなくても同じ現象が発生した。*1
Win32APIのGetLocalTimeだと正常な日時を持ってくるので、
これとサンプルで出た文字列を見比べる事で判定する。
ちなみにOSはWindows2000だが、XPでも同じ現象が出るような気がする。

void CheckTime(int nYear, int nMonth, int nDay, int nHour)
{
	time_t sNow;
	struct tm sNowTm;
	char szNowStr[1024];        
	SYSTEMTIME st;

	memset(&st, 0, sizeof(st));
	st.wYear = nYear;
	st.wMonth = nMonth;
	st.wDay = nDay;
	st.wHour = nHour;
	SetLocalTime(&st);

	time(&sNow); 
	sNowTm  = *localtime(&sNow); 
	strftime(szNowStr,  sizeof(szNowStr),  "%Y/%m/%d %H:%M:%S", &sNowTm); 

	GetLocalTime(&st);
	printf("%04d/%02d/%02d %02d:%02d:%02d,%s\n", 
		st.wYear, st.wMonth, st.wDay, 
		st.wHour, st.wMinute, st.wSecond, 
		szNowStr);

}

現象が発現したのは、2008/04/06 2:00, 2009/04/05 2:00, 2010/04/04 2:00の3つ。
どれもニュージーランドの夏時間の終わりという微妙なもの。*2
1時と3時は正常で、2時だけ何故か1時間マイナスされた時刻を持ってくる。
更にVC6.0だと正常な事からVC4.2のライブラリのバグらしいというのは確定。
というわけでWin32APIの方を使うように変更。
結構昔にVC4.2のタイムゾーンに関するバグはあったという話は聞いているけど、
未だに使われてるものは意外とありそうな気がする。


オマケ
タイムゾーン設定が保存されているレジストリキー。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation


DayLightBias 0:夏時間無効 / 0以外?:夏時間有効
DaylightStart 夏時間開始日
(全て0が並んでたら設定無し?)
StandardStart 夏時間終了日

*1:勘違いやってませんでした。orz。まぁやってないとデフォルト使うはずなんだけど。

*2:南半球なので夏時間も逆。更に9月にある夏時間の始まりでは問題は出ないというのが特に微妙なバグ。