Upgrade to Pro — share decks privately, control downloads, hide ads and more …

グローバル化はなぜ日時処理問題を引き起こすのか

 グローバル化はなぜ日時処理問題を引き起こすのか

2013年10月に私が公開したスライドです。長らくSlideShareに配置していましたが、SlideShareが広告まみれになって酷いので、Speaker Deckに移しました。以下、公開時の紹介文です。

---

「『プログラミング .NET Framework 第4版 』座談会」発表資料です。
http://atnd.org/event/E0019986/0

Atsushi Kambara

October 26, 2013
Tweet

More Decks by Atsushi Kambara

Other Decks in Programming

Transcript

  1. Charles (非UTC Ver.): Tokyo を9am にDeparture して California に7am にArrive

    したんだよ 何時間かかったか 分からない
  2. Charles (UTC Ver.): Tokyo を12am にDeparture して California に2PM にArrive

    したんだよ 14時間かかったんだね おつかれさま
  3. lヽ ノ l l l l ヽ ヽ )'ーーノ( |

    | | 、 / l| l ハヽ |ー‐''"l / U | | |/| ハ / / ,/ /|ノ /l / l l l| l U ヽ l ・ i´ | ヽ、| |r|| | //--‐'" `'メ、_lノ| / ・ / | T l トー-トヽ| |ノ ''"´` rー-/// | T | | ・ |/ | l ||、 ''""" j ""''/ | |ヽl ・ | | C | | l | ヽ, ― / | | l C | | !! | / | | | ` ー-‐ ' ´|| ,ノ| || !! | ノー‐---、,| / │l、l |レ' ,ノノ ノハ、_ノヽ / / ノ⌒ヾ、 ヽ ノハ, | ,/ ,イーf'´ /´ \ | ,/´ |ヽl | /-ト、| ┼―- 、_ヽメr' , -=l''"ハ | l ,/ | ヽ \ _,ノーf' ´ ノノ ヽ | | 、_ _ ‐''l `ー‐―''" ⌒'ー--‐'´`ヽ、_ _,ノ ノ  ̄ ̄ | /
  4. 例えば Charles が住んでいる California では 次の 2 つを使い分ける: •太平洋夏時間:UTC-7 =>

    3 月から 11 月 (夏) •太平洋標準時:UTC-8 => 11 月から 3 月 (冬)
  5. DateTime.Kind ちょくちょく邪魔する: •TimeZoneInfo の UTC => Local 変換メソッドに Kind が

    Local の DateTime を渡したら 死亡 ※DateTime.(Today|Now) の Kind は Local •WCF のクライアントとサーバーのタイムゾーン が異なり、受け渡す DateTime の Kind が Local だと、時差に応じて勝手に値が変換され る
  6. DateTimeOffset 例:Charlesの移動時間問題 Tokyo を 9 am (UTC+9) に Departure して

    California に 7 am (UTC-7) に Arrive ↓ DateTimeOffset なら普通に引き算可能 new DateTimeOffset(2013, 5, 28, 7, 0, 0, TimeSpan.FromHours(-7d)) – new DateTimeOffset(2013, 5, 28, 9, 0, 0, TimeSpan.FromHours(9d))
  7. TimeZoneInfo •ConvertTimeToUtc:Local => Utc 変換 •ConvertTimeFromUtc:Utc=> Local 変換 •GetUtcOffset:指定された日時における UTC

    との時差を返す※夏時間にも対 応 => DateTimeOffset に外から与える時差 情報はこれで取れる!!
  8. スキップされる時間 •.NET では Invalid Time と呼ぶ •TimeZoneInfo クラスに IsInvalidTime メソッド

    がある Local Time 00:00 01:00 02:00 03:00 04:00 UTC 02:00 03:00 03:00 04:00 05:00 DST (UTC-1) Invalid Time
  9. 繰り返す時間 •.NET では Ambiguous Time と呼ぶ •TimeZoneInfo クラスに IsAmbiguousTimeメ ソッドがある

    Local Time 00:00 01:00 02:00 -> 01:00 02:00 03:00 UTC 01:00 02:00 03:00 04:00 05:00 Standard (UTC-2) Ambiguous Time
  10. 繰り返す時間 •TimeZoneInfo.ConvertTimeToUtcメソッドに Ambiguous Time を渡したら、標準時間だ と仮定して変換される Local Time 00:00 01:00

    02:00 -> 01:00 02:00 03:00 UTC 01:00 02:00 03:00 04:00 05:00 Standard (UTC-2) Ambiguous Time .NET:こっちやろ
  11. スキップされる時間再び TimeZoneInfo クラスに IsInvalidTime メソッドは あるが、Invalid Time の範囲を調べるメソッ ドがない (公開されてない)

    作るしかない 作りますた(http://pastebin.com/GX3EYKbG) システムが Invalid Time を自動訂正で きる
  12. DBにはUTCで保存 根拠: •プログラムでの UTC の扱いやすさ (前述) •DB の値が Invalid/Ambiguous Time

    でないことが 保証される (UTC => Local 変換は失敗しな い) •DateTimeOffset だと、結局夏時間対応のた め別フィールドでタイムゾーン情報を持つ 必要がある
  13. DBにはUTCで保存 しんどいところ: •DB を検索する時も DB に保存する時も Local => UTC 変換が必要。となると

    Invalid/Ambiguous Time 対応が必要になる ※DateTimeOffset でも必要なのは同じ