ものがたり(旧)

atsushieno.hatenablog.com に続く

TimeZoneはトラブル・ロード(第2章)

いや別に13章まで書くつもりはないけど。

悩み中である。

TimeZone.StandardNameとTimeZone.DaylightNameをサポートするには、POSIXAPIが噛み合わない。模索する方向が全部行き詰まる。おかげさまで昨日から何もcommitしていない。まあ昨日はToLocalTime()のbugfixもやっていたのだけど。

WindowsではTimeZoneは規定の選択肢から選ぶしかない。それぞれの選択肢には、標準時と夏時間があり、それぞれ名前と標準時での時差だけが表示される。名前は常にローカライズされている。

POSIXな環境では、環境変数TZの値によってタイムゾーンが設定されるが、このときの「名前」はJSTやPSTやUTCなどであって、たとえば"Asia/Tokyo"とか"東京(標準時)"などではない。追記: いや、これは確認した環境がcygwin/mingwだったのがよろしくなかった。Linux環境ではAsia/Tokyoなどになっている模様。POSIX的にはここのデータに含まれている名称で対応しているべきなんじゃないかと思うけど、現実には対応し切れていないようだ。

時差そのものはTZで計算できるから良いのだが(それも現状ではコードが怪しいのだけど)、ローカライズされたタイムゾーン名というのは取得できない。今(というかこれを実装しようと考えたその日から)考えているのは、CLDRにあるtimeZoneNamesを引っ張ってくるやり方なのだけど、一意性を表すキーがtypeという文字列しかなくて、これに紐付ける情報がTZには無さげである。localtime()で力技で引っ張ってきたUtcOffsetをもとに、CLDRでコメントされている時差情報から逆算する方法も、ひとつの時差に複数のタイムゾーンがあっては厳しいような気がする。

アメリカでは2007年からDST (daylight saving time, いわゆる夏時間)の開始日が4月から3月、10月から11月に変わるらしいけど、.NET FrameworkのGetDaylightSavingTime()なら、引数にyearをとるので、.NETFXの更新で対応可能…というわけではなく、APIの割には、歴史的な情報を持っているわけではないようだ。wikipediaにいろいろ載っているので試してみたのだけど、どうも現在ただいまの情報に基づいてのみ変換しているようだ。

さてどーすんべ。どうもTimeZoneの名前しか救えないようだし、逃げ出して他のバグフィックスしている方が割に合う気がしなくもない。