動くコード図鑑技術記事現場の渡り方キャリア論すべての記事About
C#

定石6: JSONシリアライズでISO 8601統一

出典: C# DateTime と DateTimeOffset の違い・タイムゾーン処理の正解(業務SE本番事故編)定石6: JSONシリアライズでISO 8601統一

定石6: JSONシリアライズでISO 8601統一 (csharp)#bd2c0847de10
// ✅定石6: JSONシリアライズでKindを死守する
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
 
public class OrderEvent
{
    public Guid OrderId { get; set; }
    public DateTime CreatedAtUtc { get; set; }       // Kind=Utc想定
    public DateTimeOffset CreatedAt { get; set; }     //オフセット込み
}
 
// ❌ NG: Kind=UnspecifiedのままJSONにすると受け側でLocal解釈される
var bad = new OrderEvent { CreatedAtUtc = new DateTime(2026, 5, 8, 14, 30, 0)};
string badJson = JsonConvert.SerializeObject(bad);
// → "CreatedAtUtc":"2026-05-08T14:30:00"  ←オフセット情報なし
 
// ✅ OK: DateTimeOffset寄せで持つ、またはKind=Utcを明示
var good = new OrderEvent
{
    OrderId = Guid.NewGuid(),
    CreatedAtUtc = DateTime.UtcNow,                   // Kind=Utc
    CreatedAt    = DateTimeOffset.UtcNow,             // +00:00込み
};
var settings = new JsonSerializerSettings
{
    DateTimeZoneHandling = DateTimeZoneHandling.Utc,  //受け側で誤解されない
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
};
string goodJson = JsonConvert.SerializeObject(good, settings);
// → "CreatedAtUtc":"2026-05-08T05:30:00Z","CreatedAt":"2026-05-08T05:30:00+00:00"
▸ この snippet は実行結果未収録
▸ 実行結果は未収録です
  • id: #bd2c0847de10
  • lines: 30
  • extracted: 2026-06-10

Source収録記事

この snippet は記事の「定石6: JSONシリアライズでISO 8601統一」セクションに登場する。コードの前後の文脈・ハマりどころの解説は記事本文で。

同じ記事から

6
C#
// ✅定石1: DateTime.Kindの3パターン
var local = DateTime.Now;                                  // Kind=Local
var utc   = DateTime.UtcNow;                                // Kind=Utc
var unsp  = new DateTime(2026, 5, 8, 14, 30, 0);            // Kind=Unspecified
▶ 実行可

定石1: DateTime.Kindの3つの罠(Local / Utc / Unspecified)

#05c39f91324d
C#
// ✅定石2:サーバー処理はUtcNow、UI表示だけNow
public class OrderLog
{
    public Guid OrderId { get; set; }
未収録

定石2: DateTime.NowとDateTime.UtcNowの使い分け

#23a7f94f1fd9
C#
// ✅定石3: DateTimeOffsetでタイムゾーン情報を持ち回る
DateTimeOffset jstNow = DateTimeOffset.Now;             // JST環境なら+09:00
DateTimeOffset utcNow = DateTimeOffset.UtcNow;          // +00:00

▶ 実行可

定石3: DateTimeOffsetを使うべき場面

#ec04c241b5a6
C#
// ✅定石4: TimeZoneInfoで明示的タイムゾーン変換
var utcNow = DateTime.UtcNow;

// JSTに変換(.NET Framework / Windows: "Tokyo Standard Time")
▶ 実行可

定石4: TimeZoneInfo.ConvertTimeで明示的タイムゾーン変換

#0a3109479ee8
SQL
-- ✅定石5-a: datetimeとdatetime2の精度差
DECLARE @dt1 datetime  = '2026-05-08 14:30:00.123';
DECLARE @dt2 datetime2 = '2026-05-08 14:30:00.123';

▶ 実行可

定石5: SQL Server datetime vs datetime2 —業務系JOIN事故の温床

#b343acd30a08
C#
// ✅定石5-b: SQL Serverから読み出したDateTimeのKindはUnspecified
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("SELECT created_at FROM order_log WHERE id = @id", conn))
{
▶ 実行可

定石5: SQL Server datetime vs datetime2 —業務系JOIN事故の温床

#b11995d138a9
図鑑トップ