@prefix schema: <https://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix ks: <https://comcomponent.com/vocab/> .

<https://comcomponent.com/blog/business-app-datetime-timezone-guide/#article>
    schema:about <https://comcomponent.com/knowledge/datetime-kind/>, <https://comcomponent.com/knowledge/utc-storage-principle/> ;
    schema:mentions <https://comcomponent.com/knowledge/dotnet/>, <https://comcomponent.com/knowledge/dotnet-framework/>, <https://comcomponent.com/knowledge/datetimeoffset/>, <https://comcomponent.com/knowledge/timezoneinfo/>, <https://comcomponent.com/knowledge/timeprovider/>, <https://comcomponent.com/knowledge/iana-timezone-id/>, <https://comcomponent.com/knowledge/windows-timezone-id/>, <https://comcomponent.com/knowledge/icu/>, <https://comcomponent.com/knowledge/dst/>, <https://comcomponent.com/knowledge/roundtrip-format/>, <https://comcomponent.com/knowledge/business-date-vs-timestamp/>, <https://comcomponent.com/knowledge/ef-core-value-converter/>, <https://comcomponent.com/knowledge/sql-server-datetime2/>, <https://comcomponent.com/knowledge/w32time/>, <https://comcomponent.com/knowledge/ntp/>, <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/>, <https://comcomponent.com/knowledge/kind-loss-on-db-read/>, <https://comcomponent.com/knowledge/recurring-job-dst-anomaly/> .

<https://comcomponent.com/knowledge/datetime-kind/> a skos:Concept ;
    skos:prefLabel "DateTimeのKind"@ja ;
    skos:definition "DateTimeが持つUtc/Local/Unspecifiedの3値の属性。既定はUnspecifiedで、変換メソッドがどちらの基準とみなすかが呼び出し先ごとに異なる。"@ja ;
    skos:altLabel "Kind属性"@ja ;
    skos:altLabel "DateTimeKind" ;
    skos:altLabel "Unspecified" ;
    ks:mayCause <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> .

<https://comcomponent.com/knowledge/utc-storage-principle/> a skos:Concept ;
    skos:prefLabel "UTC保存の原則"@ja ;
    skos:definition "取得はUTC、保存と通信はUTCまたはオフセット付き、ローカル時刻への変換は画面・帳票に出す直前の1回だけに限るという日時処理の設計原則。"@ja ;
    ks:prevents <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> ;
    ks:mitigates <https://comcomponent.com/knowledge/recurring-job-dst-anomaly/> .

<https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> a skos:Concept ;
    skos:prefLabel "サーバー移設時の9時間ずれ事故"@ja ;
    skos:definition "Kindを持たない値にToLocalTime/ToUniversalTimeを適用した結果が実行マシンのタイムゾーン設定に依存し、日本時間の開発機からUTC設定のクラウドVMへ移設した日に一気に顕在化する事故。"@ja ;
    skos:altLabel "9時間ずれ"@ja .

<https://comcomponent.com/knowledge/datetimeoffset/> a skos:Concept ;
    skos:prefLabel "DateTimeOffset"@ja ;
    skos:definition "日時に加えてUTCからのオフセットを常に持ち、値単体で世界のどの瞬間かが一意に決まる.NETの型。公式ガイダンスはこれをアプリケーション開発の既定の日時型として検討するよう明記している。"@ja ;
    ks:mitigates <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> .

<https://comcomponent.com/knowledge/timezoneinfo/> a skos:Concept ;
    skos:prefLabel "TimeZoneInfo"@ja ;
    skos:definition "タイムゾーンの定義や夏時間の調整規則を扱い、UTCとローカル時刻を相互変換する.NETのクラス。"@ja ;
    skos:altLabel "ConvertTimeFromUtc" ;
    skos:altLabel "ConvertTimeToUtc" ;
    ks:uses <https://comcomponent.com/knowledge/windows-timezone-id/> .

<https://comcomponent.com/knowledge/iana-timezone-id/> a skos:Concept ;
    skos:prefLabel "IANAタイムゾーンID"@ja ;
    skos:definition "IANA tz databaseが定めるタイムゾーンの識別子。Linuxや海外SaaS、他言語との連携で共通に通じる。"@ja ;
    skos:altLabel "Asia/Tokyo" ;
    skos:altLabel "IANA tz database" .

<https://comcomponent.com/knowledge/windows-timezone-id/> a skos:Concept ;
    skos:prefLabel "WindowsタイムゾーンID"@ja ;
    skos:definition "Windowsのレジストリが管理するタイムゾーンの識別子。.NET Framework時代のTimeZoneInfoはこのIDしか使えなかった。"@ja ;
    skos:altLabel "Tokyo Standard Time" .

<https://comcomponent.com/knowledge/icu/> a skos:Concept ;
    skos:prefLabel "ICU(International Components for Unicode)"@ja ;
    skos:definition "国際化処理を担うライブラリ。.NET 5以降はカルチャやタイムゾーンIDの解決をこれに任せており、Windows上でのIANA ID解決はICUに依存する。"@ja .

<https://comcomponent.com/knowledge/dst/> a skos:Concept ;
    skos:prefLabel "夏時間(DST)"@ja ;
    skos:definition "時計を進めて日照時間を有効活用する制度。切り替え日に、存在しない時刻と曖昧な時刻という2種類の異常な時刻を生む。"@ja ;
    skos:altLabel "Daylight Saving Time" ;
    skos:altLabel "サマータイム"@ja ;
    ks:verifiedBy <https://comcomponent.com/knowledge/timezoneinfo/> ;
    ks:mayCause <https://comcomponent.com/knowledge/recurring-job-dst-anomaly/> .

<https://comcomponent.com/knowledge/recurring-job-dst-anomaly/> a skos:Concept ;
    skos:prefLabel "DST切替日の定期実行の多重実行・欠測"@ja ;
    skos:definition "現地時刻基準の定期ジョブが、夏時間の開始日に存在しない時刻としてスキップされ、終了日には曖昧な時刻として2回起動する現象。"@ja .

<https://comcomponent.com/knowledge/roundtrip-format/> a skos:Concept ;
    skos:prefLabel "ラウンドトリップ書式(\"o\")"@ja ;
    skos:definition "DateTimeのKindやDateTimeOffsetのオフセットを文字列に保持し、DateTimeStyles.RoundtripKindでのパースにより元の値へ復元できるISO 8601準拠の標準書式。"@ja ;
    skos:altLabel "ISO 8601" ;
    skos:altLabel "o書式"@ja .

<https://comcomponent.com/knowledge/business-date-vs-timestamp/> a skos:Concept ;
    skos:prefLabel "業務日付とタイムスタンプの区別"@ja ;
    skos:definition "「7月3日の日報」のような業務日付と、世界で一意な時点を表すタイムスタンプを別の型・列として扱うべきという区別。業務日付は「どのタイムゾーンで日付を切るか」を仕様で決める必要がある。"@ja ;
    skos:altLabel "業務日付"@ja ;
    skos:altLabel "タイムスタンプ"@ja .

<https://comcomponent.com/knowledge/ef-core-value-converter/> a skos:Concept ;
    skos:prefLabel "EF Coreの値コンバーター"@ja ;
    skos:definition "DB列の読み書き時にDateTimeを一括して正規化・Kind復元できるEF Coreの機能。読み出し時にKindをUtcへ明示的に復元できる。"@ja ;
    ks:uses <https://comcomponent.com/knowledge/datetime-kind/> ;
    ks:mitigates <https://comcomponent.com/knowledge/kind-loss-on-db-read/> .

<https://comcomponent.com/knowledge/sql-server-datetime2/> a skos:Concept ;
    skos:prefLabel "SQL Serverのdatetime2型"@ja ;
    skos:definition "基準情報を持たずUTCで保存する列の本命とされる、新規採用が推奨されるSQL Serverの日時型。"@ja ;
    skos:altLabel "datetime2" ;
    skos:altLabel "datetimeoffset(SQL Server)" ;
    ks:mayCause <https://comcomponent.com/knowledge/kind-loss-on-db-read/> ;
    ks:recommendedFor <https://comcomponent.com/knowledge/utc-storage-principle/> .

<https://comcomponent.com/knowledge/kind-loss-on-db-read/> a skos:Concept ;
    skos:prefLabel "DB読み出し時のKind消失"@ja ;
    skos:definition "datetime2やSQLiteのTEXTなど基準情報を持たない型からDateTimeを読み出すと既定でKind=Unspecifiedになり、保存時はUTCで統一していたはずの値に対して二重変換が起きる事故を招くこと。"@ja .

<https://comcomponent.com/knowledge/ntp/> a skos:Concept ;
    skos:prefLabel "NTP(Network Time Protocol)"@ja ;
    skos:definition "ネットワーク上の時刻源から時刻サンプルを取得し、クロックフィルターやクロック選択アルゴリズムで時計を調整するための標準プロトコル。"@ja ;
    skos:altLabel "Network Time Protocol" .

<https://comcomponent.com/knowledge/timeprovider/> a skos:Concept ;
    skos:prefLabel "TimeProvider"@ja ;
    skos:definition ".NET 8で標準搭載された、現在時刻とローカルタイムゾーンをテストで差し替え可能にする時刻抽象。.NET Framework 4.6.2以降でもNuGetパッケージで利用できる。"@ja ;
    skos:altLabel "FakeTimeProvider" ;
    skos:altLabel "Microsoft.Bcl.TimeProvider" .

<https://comcomponent.com/knowledge/dotnet/> a skos:Concept ;
    skos:prefLabel ".NET(Core以降)"@ja ;
    skos:definition ".NET Frameworkの後継となる、クロスプラットフォーム対応の.NETランタイム(.NET 5以降)。"@ja ;
    skos:altLabel ".NET Core" ;
    skos:altLabel "モダンな.NET"@ja .

<https://comcomponent.com/knowledge/dotnet-framework/> a skos:Concept ;
    skos:prefLabel ".NET Framework"@ja ;
    skos:definition "Windowsのコンポーネントとして扱われ、インストールされているOSのライフサイクルに沿ってサポートされるランタイム。System.Messagingの対象範囲。"@ja .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/datetime-kind/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> ;
    schema:description "Kindが既定でUnspecifiedの値にToLocalTime/ToUniversalTimeを適用すると実行マシンのタイムゾーン設定に依存した黙った変換が起こり、9時間ずれ事故の典型的な発生源になる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.datetime.kind> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/utc-storage-principle/> ;
    rdf:predicate ks:prevents ;
    rdf:object <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> ;
    schema:description "取得・保存・通信をUTCまたはオフセット付きで統一し表示直前だけ変換する原則を守れば、環境依存の暗黙変換が構造的に起きない"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/datetime/choosing-between-datetime> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/datetimeoffset/> ;
    rdf:predicate ks:mitigates ;
    rdf:object <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> ;
    schema:description "DateTimeOffsetは値単体でUTCからのオフセットを持つためKindの暗黙解釈に頼る余地がなく、この記事で扱う事故の大半が構造的に起きなくなる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/datetime/choosing-between-datetime> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/timezoneinfo/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/datetime-kind/> ;
    schema:description "TimeZoneInfo.ConvertTimeなどDateTimeを受け取る変換APIを使う場合、そのAPIはDateTimeのKindと変換元タイムゾーンの整合を検査し、不一致だとArgumentExceptionになる。DateTimeOffsetを受け取るオーバーロードにはKindが無く、この検査も働かない"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.timezoneinfo.converttime> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/timezoneinfo/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/iana-timezone-id/> ;
    schema:description ".NET 6以降のTimeZoneInfo.FindSystemTimeZoneByIdはIANA IDを受け付け、システムに無い側は自動で変換して解決する"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/whats-new/dotnet-6> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/timezoneinfo/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/windows-timezone-id/> ;
    schema:description "TimeZoneInfo.FindSystemTimeZoneByIdはWindows IDも受け付け、TryConvertWindowsIdToIanaIdなどの相互変換APIも提供する"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/whats-new/dotnet-6> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/iana-timezone-id/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/icu/> ;
    schema:description "Windows上でのIANA IDの解決はICUライブラリに依存し、NLSモードやグローバリゼーション不変モードでは解決できない"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/core/extensions/globalization-icu> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dst/> ;
    rdf:predicate ks:verifiedBy ;
    rdf:object <https://comcomponent.com/knowledge/timezoneinfo/> ;
    schema:description "夏時間の切り替え日に生じる存在しない時刻・曖昧な時刻は、TimeZoneInfo.IsInvalidTime/IsAmbiguousTimeで確認できる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.timezoneinfo.isinvalidtime> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dst/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/recurring-job-dst-anomaly/> ;
    schema:description "現地時刻の特定時刻に動く定期ジョブは、DST開始日にその時刻が存在せずスキップされ、終了日には2回存在するために二重起動する"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.timezoneinfo.isinvalidtime> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/utc-storage-principle/> ;
    rdf:predicate ks:mitigates ;
    rdf:object <https://comcomponent.com/knowledge/recurring-job-dst-anomaly/> ;
    schema:description "スケジュール基準をUTC(またはDSTの無いタイムゾーン)にし、処理を冪等にし、集計キーを業務日付で持てば、DSTによる多重実行・欠測の問題が解消する"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.timezoneinfo.isinvalidtime> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/utc-storage-principle/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/roundtrip-format/> ;
    schema:description "境界を文字列で越えるときはISO 8601準拠のラウンドトリップ書式\"o\"を使い、Kindやオフセットを保持したまま復元できるようにする"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/base-types/standard-date-and-time-format-strings> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/business-date-vs-timestamp/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/timezoneinfo/> ;
    schema:description "業務日付をどのタイムゾーンで切るかを仕様で決め、UtcNowを該当タイムゾーンへ変換してから日付を切る必要がある"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.timezoneinfo.converttime> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/ef-core-value-converter/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/datetime-kind/> ;
    schema:description "EF Coreの値コンバーターはUTC以外の値を境界で正規化し、読み出し時にKindをUtcへ復元することでKindの扱いを一括宣言する"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.datetime.kind> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sql-server-datetime2/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/kind-loss-on-db-read/> ;
    schema:description "datetime2は基準情報を持たないため、そこから読み出したDateTimeは既定でKind=Unspecifiedになる"@ja ;
    ks:evidence <https://learn.microsoft.com/sql/t-sql/data-types/datetime-transact-sql> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/ef-core-value-converter/> ;
    rdf:predicate ks:mitigates ;
    rdf:object <https://comcomponent.com/knowledge/kind-loss-on-db-read/> ;
    schema:description "EF Coreの値コンバーターで読み出し時にDateTime.SpecifyKindを通せば、DB境界でのKind消失を補える"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.datetime.kind> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/kind-loss-on-db-read/> ;
    rdf:predicate ks:mayCause ;
    rdf:object <https://comcomponent.com/knowledge/timezone-nine-hour-shift-bug/> ;
    schema:description "読み出し時にKindが消えた値へさらにToUniversalTime等の変換をかけると、二重変換や9時間ずれと同種の事故につながる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/api/system.datetime.kind> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/utc-storage-principle/> ;
    rdf:predicate ks:requires ;
    rdf:object <https://comcomponent.com/knowledge/ntp/> ;
    schema:description "複数マシンにまたがる絶対時刻としてUTC基準の値を突き合わせる場合は、そもそもマシンの時計がNTPでネットワーク上の時刻源と正しく同期されている必要がある(Windows環境ではこの同期をw32timeサービスが担う)。UTCで保存して表示直前に変換するという表現上の原則自体は、時計が同期されていなくても成り立つ"@ja ;
    ks:evidence <https://learn.microsoft.com/windows-server/networking/windows-time-service/windows-time-service-top> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/utc-storage-principle/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/timeprovider/> ;
    schema:description "テストで時刻を差し替え可能にしたい場合、発生時刻の取得はTimeProvider.GetUtcNow()に統一し、DateTime.Nowの直書きをやめる"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/datetime/timeprovider-overview> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dotnet/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/timeprovider/> ;
    schema:description "TimeProviderは.NET 8以降に標準搭載された時刻抽象である"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/datetime/timeprovider-overview> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/dotnet-framework/> ;
    rdf:predicate ks:uses ;
    rdf:object <https://comcomponent.com/knowledge/timeprovider/> ;
    schema:description ".NET Framework 4.6.2以降でもMicrosoft.Bcl.TimeProviderパッケージで同じTimeProvider型が使える"@ja ;
    ks:evidence <https://learn.microsoft.com/dotnet/standard/datetime/timeprovider-overview> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "context-dependent" .

[] a rdf:Statement ;
    rdf:subject <https://comcomponent.com/knowledge/sql-server-datetime2/> ;
    rdf:predicate ks:recommendedFor ;
    rdf:object <https://comcomponent.com/knowledge/utc-storage-principle/> ;
    schema:description "UTCで保存する列の本体としては、精度が高く公式に新規採用が推奨されるdatetime2が本命とされる"@ja ;
    ks:evidence <https://learn.microsoft.com/sql/t-sql/data-types/datetime-transact-sql> ;
    ks:verifiedAt "2026-08-01" ;
    ks:certainty "established" .
