TimeZoneはトラブル・ロード(第1章)
何かDateTime.Parse()やらDouble.ToString()やら、いろんなバグが降ってきましたよおい。DateTimeやりたくないんだよねえ…これ環境に依存するわ、地域に依存するわ、Parse()はCOMに依存するわで、信用性がほとんど無いクラスなので。こういうのはMS.NET互換性まんせー言ってる奴が率先してやってほしい。
DateTime.Parse applies timezone incorrectly around daylight saving time transition
サマータイムがある国でUTCと時差がある場合に夏時間から冬時間への切り替えがある辺りの時刻が正しくDateTime.ParseExact()できない、というやや厳しい条件で起こる問題。結論から言えば、原因はこの人の推測で正解で、TimeZone.GetUtcOffset()はDSTのあるローカルタイムからUTCに変換するために使うことはできても、UTCから変換するために使うことは出来ないのである。
とりあえずLinux環境が死んだままなので、ランタイムをいじって、環境変数TZに影響を受けるように変更したら、どうやらDSTを再現できたらしい。直すならTimeZoneのicallだろうと思っていたが、本当にParseExact()だけの問題だった。便利だからicallはこのままこれで残しておこうかな。
DateTime.ToLocalTime()のコードを眺めてみると、なにやらいったんローカルタイムに変換した上でUTCでの時刻から取得したoffsetと新しいoffsetを比較して、差分があったら縮めるという、ややこしいことをしているようだ。