夏時間が適用されるタイムゾーンにおける mktime 関数利用時の注意事項について

こんにちは。Visual Studio サポート チームです。

今回は、夏時間が適用されるタイムゾーンにおいて Visual C++ の mktime 関数を利用する際に注意が必要となる点をご紹介します。

 

夏時間 (DST : Daylight Saving Time) とは

夏時間は、1 年のうちの夏を中心とした期間に、日照時間を有効利用する目的で標準時を 1 時間早める制度です。 例えば、米国西部で利用されている太平洋標準時 (PST) では、夏時間として太平洋夏時間 (PDT) が採用されており、3 月の第 2 日曜日の午前 2 時から、11 月の第 1 日曜日の午前 2 時までの期間が夏時間として扱われ、その前後で、その地域における標準時が切り替わります。

現在の日本では採用されていませんが、欧米を中心とした諸外国では広く採用されているため、国際化に対応したシステムでは夏時間を考慮する必要があるケースも増えていると思います。

 

スキップされる 1 時間と、2 度繰り返される 1 時間

標準時との切り替えのため、夏時間の開始時には、時計の上では 1 時間がスキップされ、夏時間の終了時には 1 時間が 2 度繰り返されような状況となります。

PDT の場合、2016 年を例にとると、以下のように標準時が切り替えられ、タイムゾーンに PST が設定されている Windows OS のシステム時刻は、これに従って切り替えられます。

 

● 夏時間の開始時

3 月 13 日 (日) 午前 1:59:59 (非 DST)

(1 秒経過)

3 月 13 日 (日) 午前 3:00:00 (DST)

※ 2:00 – 3:00 の 1 時間がスキップされます。

 

● 夏時間の終了時

11 月 6 日 (日) 午前 1:59:59 (DST)

(1 秒経過)

3 月 13 日 (日) 午前 1:00:00 (非 DST)

※ 1:00 – 2:00 の 1 時間が、2 度繰り返されます。

 

mktime 関数利用時の注意点

mktime 関数では、引数の tm 構造体として、前述の夏時間終了前後の “繰り返される 1 時間” の時刻が指定され、かつ、tm_isdst フィールドに負の値が指定されている場合は、同時刻が夏時間なのか、夏時間終了後なのかを判断することができず、意図した結果を得られない場合があります。

このため、mktime 関数の引数に、夏時間終了前後の ”繰り返される 1 時間” の時刻を指定する場合は、必ず、tm_isdst フィールドにて正の値または 0 を指定して、同時刻が夏時間なのか、夏時間終了後の時刻なのかを明示する必要がある点にご注意ください。

なお、現在のシステム時刻が夏時間であるかどうかについては GetDynamicTimeZoneInformation 関数 の戻り値などから確認することが可能です。

 

詳細

mktime 関数は、引数で指定された tm 構造体のローカル時刻を time_t 型に変換します。tm 構造体には tm_isdst というフィールドが含まれますが、これには以下の 3 通りの値を設定することができます。

 

tm_isdst に正の値を設定する : 夏時間が適用されていることを示します。

tm_isdst に 0 を設定する : 夏時間が適用されていないことを示します。

tm_isdst に負の値を設定する : 夏時間が適用されているかどうか不明であることを示します。

 

関数リファレンスに記載の通り、tm_isdst に負の値を設定して mktime 関数を実行した場合、Visual C++ ランタイムは、いくつかの方法で夏時間が適用されているかどうかの判断を試みます。

ここで、この判断では、mktime 関数を実行した実行環境が、現在、夏時間に属しているかどうかは関係なく、あくまで、TZ 環境変数や GetTimeZoneInformation 関数を通じて取得されたタイムゾーンの情報をもとに、引数の tm 構造体で指定された時刻が夏時間に該当するかどうかを判断しているという点に注意が必要です。GetTimeZoneInformation 関数の戻り値からは、現在、その環境が夏時間に属しているかどうか判断することが可能ですが、この情報は mktime 関数の内部では利用されません。なぜなら、mktime 関数の引数には、現在時刻だけでなく、任意の時刻を指定することが可能であるため、mktime 関数は指定されたどの時刻にも応じられるよう、夏時間の判断を行う必要があるためです。

このことから、mktime 関数では、前述の夏時間終了時における “繰り返される 1 時間” の時刻が指定された場合、tmi_isdst が負の値の場合は、同時刻が夏時間の時刻なのか、夏時間終了後の時刻なのか、判断することができません。

 

日本では馴染みの少ない夏時間ですが、海外で動作するシステムを開発される際には、本稿のような点にもご注意いただけましたら幸いです。