日期時間處理是開發高頻需求,.NET 從 1.0 的 DateTime、2.0 的 Nullable<DateTime>、3.5 的 DateTimeOffset 到 TimeZoneInfo,逐步解決時區、可空性與跨時區識別問題。本文系統整理各類型特性、轉換規則與選用指南。
Kind 屬性標示 Unspecified/Utc/Local,不攜帶時差資訊,跨時區易產生歧義。DateTime 值與 Offset(相對 UTC 時差),唯一識別一個時間點,不依賴特定時區,適合跨時區應用。Console.WriteLine(DateTime.Now); // 2008/8/26 23:01:48
Console.WriteLine(DateTimeOffset.Now); // 2008/8/26 23:01:48 +08:00
DateTime dateA = new DateTime(2008,8,26,23,1,48);
DateTimeOffset dateB = new DateTimeOffset(2008,8,26,23,1,48, new TimeSpan(4,0,0)); // UTC+4
關鍵在於 DateTime.Kind:
DateTime dateB = DateTime.SpecifyKind(dateA, DateTimeKind.Utc);
DateTimeOffset dateC = dateB; // 隱含轉換,Offset = +00:00
DateTimeOffset → DateTime 三種屬性:
DateTime:Unspecified 幾何值UtcDateTime:UTC 時間(自動換算)LocalDateTime:本地時間(經 UTC 轉換)DateTime 即可。Kind = DateTimeKind.Utc 並統一以 UTC 儲存/傳輸。TimeZone 僅能識別本地時區;TimeZoneInfo 提供全球所有时區資料、轉換、列舉功能,完全取代前者:
TimeZoneInfo eastern = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
DateTimeOffset easternDate = TimeZoneInfo.ConvertTime(chinaDate, eastern);
未來開發應棄用 TimeZone,全面採用 TimeZoneInfo。