知識マップ: 業務アプリの日時とタイムゾーン ── DateTimeの罠からUTC保存の原則、テスト設計まで
記事「業務アプリの日時とタイムゾーン ── DateTimeの罠からUTC保存の原則、テスト設計まで」の主張を、概念と関係(エッジ)に分解した知識グラフの全体です。各関係には根拠・確認日・確度が付いています。
業務アプリの日時事故は、DateTimeが既定で持つKind=Unspecifiedの値にToLocalTime/ToUniversalTimeが黙って基準を仮定することに起因し、実行マシンのタイムゾーン設定に依存するため開発機では再現せずサーバー移設の日に9時間ずれとして顕在化する。対策はUTC保存の原則で、取得・保存・通信はDateTimeOffsetやUTCのDateTimeで統一し、ラウンドトリップ書式で境界を越え、ローカル時刻への変換は表示直前の1回に限る。TimeZoneInfoによる変換はKindとの整合を要求し、IANA IDの解決はWindows上ではICUに依存し、夏時間の切替日にはIsInvalidTime/IsAmbiguousTimeで異常な時刻を確認できる。SQL Serverのdatetime2列やEF Coreの値コンバーターはDB境界でのKind消失に対応し、TimeProviderを注入すれば年跨ぎやDST切替日のバグをテストで再現できる。
flowchart LR
accTitle: 業務アプリの日時とタイムゾーン処理の知識マップ
accDescr: DateTimeのKindが引き起こす9時間ずれ事故の構造と、UTC保存の原則がそれをどう防ぐか、TimeZoneInfoやDST、DBとの境界、TimeProviderによるテストとの関係を示す図
datetime_kind["DateTimeのKind"]
utc_storage_principle["UTC保存の原則"]
timezone_nine_hour_shift_bug["サーバー移設時の9時間ずれ事故"]
datetimeoffset["DateTimeOffset"]
timezoneinfo["TimeZoneInfo"]
iana_timezone_id["IANAタイムゾーンID"]
windows_timezone_id["WindowsタイムゾーンID"]
icu["ICU(International Components for Unicode)"]
dst["夏時間(DST)"]
recurring_job_dst_anomaly["DST切替日の定期実行の多重実行・欠測"]
roundtrip_format["ラウンドトリップ書式(#quot;o#quot;)"]
business_date_vs_timestamp["業務日付とタイムスタンプの区別"]
ef_core_value_converter["EF Coreの値コンバーター"]
sql_server_datetime2["SQL Serverのdatetime2型"]
kind_loss_on_db_read["DB読み出し時のKind消失"]
ntp["NTP(Network Time Protocol)"]
timeprovider["TimeProvider"]
dotnet[".NET(Core以降)"]
dotnet_framework[".NET Framework"]
datetime_kind -->|"原因になり得る"| timezone_nine_hour_shift_bug
utc_storage_principle -->|"防止する"| timezone_nine_hour_shift_bug
datetimeoffset -->|"軽減する"| timezone_nine_hour_shift_bug
timezoneinfo -.->|"前提とする"| datetime_kind
timezoneinfo -.->|"利用する"| iana_timezone_id
timezoneinfo -->|"利用する"| windows_timezone_id
iana_timezone_id -.->|"前提とする"| icu
dst -->|"で確認できる"| timezoneinfo
dst -->|"原因になり得る"| recurring_job_dst_anomaly
utc_storage_principle -->|"軽減する"| recurring_job_dst_anomaly
utc_storage_principle -.->|"利用する"| roundtrip_format
business_date_vs_timestamp -.->|"前提とする"| timezoneinfo
ef_core_value_converter -->|"利用する"| datetime_kind
sql_server_datetime2 -->|"原因になり得る"| kind_loss_on_db_read
ef_core_value_converter -->|"軽減する"| kind_loss_on_db_read
kind_loss_on_db_read -.->|"原因になり得る"| timezone_nine_hour_shift_bug
utc_storage_principle -.->|"前提とする"| ntp
utc_storage_principle -.->|"利用する"| timeprovider
dotnet -.->|"利用する"| timeprovider
dotnet_framework -.->|"利用する"| timeprovider
sql_server_datetime2 -->|"推奨される対応"| utc_storage_principle
概念間の関係(全21件)
図と同じ関係を文章でも列挙します。表示している文と機械可読な意味データ(RDFa)は同じ要素に載っています。確度が「確立した関係」のものは直接の関係として、「条件付きの関係」のものは成立条件つきの言明(rdf:Statement)として表現しています。
- DateTimeのKindはサーバー移設時の9時間ずれ事故の原因になることがあります。
- UTC保存の原則はサーバー移設時の9時間ずれ事故を防ぎます。
- DateTimeOffsetはサーバー移設時の9時間ずれ事故を軽減します。
- TimeZoneInfoはDateTimeのKindを前提とします。
- TimeZoneInfoはIANAタイムゾーンIDを利用します。
- TimeZoneInfoはWindowsタイムゾーンIDを利用します。
- IANAタイムゾーンIDはICU(International Components for Unicode)を前提とします。
- 夏時間(DST)はTimeZoneInfoで確認できます。
- 夏時間(DST)はDST切替日の定期実行の多重実行・欠測の原因になることがあります。
- UTC保存の原則はDST切替日の定期実行の多重実行・欠測を軽減します。
- UTC保存の原則はラウンドトリップ書式("o")を利用します。
- 業務日付とタイムスタンプの区別はTimeZoneInfoを前提とします。
- EF Coreの値コンバーターはDateTimeのKindを利用します。
- SQL Serverのdatetime2型はDB読み出し時のKind消失の原因になることがあります。
- EF Coreの値コンバーターはDB読み出し時のKind消失を軽減します。
- DB読み出し時のKind消失はサーバー移設時の9時間ずれ事故の原因になることがあります。
- UTC保存の原則はNTP(Network Time Protocol)を前提とします。
- UTC保存の原則はTimeProviderを利用します。
- .NET(Core以降)はTimeProviderを利用します。
- .NET FrameworkはTimeProviderを利用します。
- SQL Serverのdatetime2型はUTC保存の原則に対する本記事の推奨です。
主要概念の定義
機械可読データ
このページはサイトの知識グラフ(_data/knowledge/)から自動生成されています。誤りの指摘はお問い合わせからお願いします。