閏時

本件は2013-10-09の記事と重複するのですが、前回はWhen::Coordinates::Pair
クラスの側からの視点ではなかったので再度取り上げておきます。

iCalendarの規格(RFC5545)では日時は、

 (1) Z終端で表現するUTC
 (2) タイムゾーン付の日時
 (3) タイムゾーンのないローカルタイム

の何れかで表現されます。(3)は暗黙に現在地のタイムゾーンが省略されたものと
みなせます。

(2) は、

 TZID=America/New_York:1997-10-26T01:30:00

のような文字列です。

ところが困ったことに、一日が日没から始まる暦で同じ時分秒が一日に2度起った
のと類似の事態が起こってしまいます。この時刻は夏時間から標準時間に戻る際に
繰り返す1時間の中に含まれるからです。

実際、2013-10-09の記事にも書きましたように TZInfo を生で使うと、

 tz = TZInfo::Timezone.get('America/New_York')
 tz.period_for_local(DateTime.new(1997,10,26,1,30,0))

で、 TZInfo::AmbiguousTime 例外が発生します。

これは TZInfo のバグではなくもともとの RFC5545 に問題があるのです。

when.exe Ruby 版では“=”を使ってこの問題を回避します[1]
“=”はWhen.exe Standard Representationの記法で「閏時」を意味します。

 p when? 'TZID=America/New_York:1997-10-26T01:30:00' #=> 1997-10-26T01:30:00-04:00
 p when? 'TZID=America/New_York:1997-10-26T01=30:00' #=> 1997-10-26T01:30:00-05:00
 p when? 'TZID=America/New_York:1997-10-26T02:30:00' #=> 1997-10-26T02:30:00-05:00
 p when? 'TZID=America/New_York:1997-10-26T03:30:00' #=> 1997-10-26T03:30:00-05:00

[1] iCalendar がこの問題をどう回避しているのかはよく知りません。

この記事へのコメント

この記事へのトラックバック