レシピ1.8 夏時間のチェック
問題
現在のロケールの時刻が夏時間かどうかを知りたい。
解決
Timeオブジェクトを生成し、そのisdstメソッドをチェックする。
Time.local(2006,1,1) # => Sun Jan 01 00:00:00 EST 2006 Time.local(2006,1,1).isdst # => false Time.local(2006,10,1) # => Sun Oct 01 00:00:00 EDT 2006 Time.local(2006,10,1).isdst # => true
解説
UTC時間を表す Timeオブジェクトは、 isdstが呼び出されると常にfalseを返す。何故なら、UTCは一年中同じ時間だからだ。他のTimeオブジェクトは、Time オブジェクトの生成に使われたロケールの時間を調べる。通常は、オブジェクトを生成したコンピュータのシステムロケールである。ロケールの設定を変更する方法については、レシピ1.7を参照のこと。次のコードは、アメリカの夏時間に関連するルールの一部を具体的に示している。
eastern = Time.local(2006, 10, 1) # => Sun Oct 01 00:00:00 EDT 2006 eastern.isdst # => true ENV[' TZ '] 'US/Pacific' pacific = Time.local(2006, 10, 1) # => Sun Oct 01 00:00:00 PDT 2006 pacific.isdst # => true # ナバホ居留地を除き、アリゾナ州では夏時間を使用しない ENV[' TZ '] 'America/Phoenix' arizona = TIme.local(2006, 10, 1) # => Sun Oct 01 00:00:00 MST 2006 arizona.isdst # => faluse # 最後に、元のタイムゾーンに戻す ENV[' TZ '] = nil
Timeクラスに使用されているCライブラリは、特定のタイムゾーンやロケールの歴史にまたがる、複雑な時間ルールに対処している。例えば、アメリカで夏時間が制定されたのは1918年のことだが、その後間もなく、ほとんどのロケールで廃止された。Cライブラリが使用する「zoneinfo」ファイルには、他の多くのルールとともに、この情報が含まれている。
# 夏時間は1918年3月31日に施行された Time.local(1918, 3, 31).isdst # => faluse Time.local(1918, 4, 1).isdst # => true Time.local(1919, 4, 1).isdst # => true # 連邦法は1919年に廃止されたが、 # 一部の地域では夏時間を使用し続けていた ENV[' TZ '] = 'US/Pacific' Time.local(1920, 4, 1) # => Thu Apr 01 00:00:00 PAT 1920 ENV[' TZ '] = nil Time.local(1920, 4, 1) # => ThuApr 01 00:00:00 EDT 1920 # 第二次世界大戦中に再び夏時間が導入された Time.local(1942, 2, 9) # => Mon Feb 09 00:00:00 EST 1942 Time.local(1942, 2, 10) # => Tue Feb 10 00:00:00 EWT 1942 # EWTは”Eastern War Time”の略
アメリカでは、2007年から夏時間を3月から11月までに拡大する法案が2005年に可決された。zoneinfoファイルがどれくらい古いかによっては、2007年以降の日付に対して生成されるTimeオブジェクトに新しい法律が反映されない可能性がある。
Time.local(2007, 3, 13) # => Tue Mar 13 00:00:00 EDT 2007 # コンピュータによっては、この時間がESTであると誤解するかもしれない
これは一般的な観念を例証している。議員たちは法案を可決させることしか眼中にない。従って、Timeオブジェクトが1年以上先の時間を表すとしたら、isdstが正確であることを当てにすべきではない。実際にその時刻になった時、そのロケールでは夏時間のルールが変更されているかもしれない。
DateクラスにはCライブラリが使用されておらず、タイムゾーンやロケールを全く認識しないため、夏時間のことも認識しない。
参照
・レシピ1.7
・「zoneinfo」データベースに含まれている情報(http://www.twinsun.com/tz/tz-link.htm)