

【茶包射手筆記】重新認識 DateTime.Parse() 時區問題
source link: https://blog.darkthread.net/blog/datetime-parse-timezone-issue/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【茶包射手筆記】重新認識 DateTime.Parse() 時區問題-黑暗執行緒
收到友人貢獻茶包一枚。
.NET DateTime.Parse() 有其好用之處,可以解析各種日期時間格式:

Console.WriteLine(DateTime.Parse("2022-06-01"));
Console.WriteLine(DateTime.Parse("2022/06/01"));
Console.WriteLine(DateTime.Parse("06/2022"));
Console.WriteLine(DateTime.Parse("2022/06/01 21:00"));
Console.WriteLine(DateTime.Parse("6/1/2022 9:00:00 PM"));
Console.WriteLine(DateTime.Parse("2022/6/1 下午 09:00:00"));
Console.WriteLine(DateTime.Parse("Wed, 1 Jun 2022 13:00:00 GMT"));
之前有研究過 DateTime.Parse(),甚至踩過數字 3.1416 被 DateTime.Parse() 解析成 1416-03-01 的雷,對於輸入格式較固定的情境,我偏好 DateTime.ParseExact(),
今天的案例讓我復習到 DateTime.Parse() 決定時區的規則:
一般來說,DateTime.Parse 傳回 DateTime 物件的 Kind 屬性為 DateTimeKind.Unspecified,但在以下情況則會轉為 Local 或 Utc:
- 日期時間字串包含時區資訊,例如:Z 或 +08:00 結尾、GMT 字樣
轉換為本地時間,Kind = DateTimeKind.Local - 日期時間字串包含時區資訊,DateTimeStyles 參數包含 AdjustToUniversal
轉換成 UTC 時間,Kind = DateTimeKind.Utc - 字串包含 Z 或 GMT,且 DateTimeStyles 參數包含 RoundtripKind
解析為 UTC 時間,Kind = DateTimeKind.Utc
實測驗證如下:
void Main()
{
test("2022-06-01");
test("2022-06-01 00:00");
Console.WriteLine("\n日期時間字串包含時區資訊");
test("2022-06-01+08:00");
test("2022-06-01+00:00");
test("2022-06-01T00:00:00Z");
test("2022-06-01Z");
Console.WriteLine("\n日期時間字串包含時區資訊 + AdjustToUniversal");
test("2022-06-01Z", DateTimeStyles.AdjustToUniversal);
test("2022-06-01+08:00", DateTimeStyles.AdjustToUniversal);
test("2022-06-01+08:00", DateTimeStyles.AdjustToUniversal);
//不合條件(無時區資訊)
test("2022-06-01", DateTimeStyles.AdjustToUniversal);
Console.WriteLine("\n日期時間字串包含Z、GMT + RoundtripKind");
test("2022-06-01 Z", DateTimeStyles.RoundtripKind);
test("2022-06-01 GMT", DateTimeStyles.RoundtripKind);
//不合條件(非 Z 或 GMT)
test("2022-06-01+08:00", DateTimeStyles.RoundtripKind);
test("2022-06-01+00:00", DateTimeStyles.RoundtripKind);
}
void test(string t, DateTimeStyles s = DateTimeStyles.None)
{
var d = DateTime.Parse(t, null, s);
Console.WriteLine(d.Kind + " | " + d.ToString());
}
回到茶包案例:程式用 DateTime.Parse() 解析外部傳入的 yyyy-MM-dd 字串轉為 DateTime 存入資料庫。資料來源意外改變了日期格式,在 yyyy-MM-dd 之外加上 +00:00 時區,由 2022-06-01 改為 2022-06-01+00:00,依上述規則,解析出來的 DateTime 原本是 Unspecified 2022-06-01 00:00:00,現在變成 Local 2022-06-01 08:00:00,程式沒出錯但時間差了八小時,費了點功夫追查才找出原因。
如果用 DateTime.ParseExact() 可以避免嗎?
如上所示,ParseExact 只要格式改變,解析時便會直接噴錯,遠比錯誤資料流入後端程序容易偵測及善後。因此,我認為對固定格式來源使用 ParseExact() 是較好的設計。
- Posted in
- .NET
and has 2 comments
Comments
# 2022-06-02 09:43 AM by 赫達利 協理 JOJO徐
黑暗大大,您好:
在下時常拜讀您的文章, 有許多文章都協助在下處理掉難解的問題 為了希望之後本公司其他工程師也可以方便地找到您的文章增進知識 並能增加本公司網站的活絡度 因此在下想要將您的文章分享在在下任職的公司官網當知識分享文章 並統一會使用您的Logo與文末連結宣告出處為此部落格,以宣告文章作者為您 且保證不會用於商業用途 請問能否同意本公司分享您的文章?? 感謝您的回應
本公司的網址 https://www.gomoney.com.tw/ Email:[email protected]
Post a comment
CommentRecommend
-
11
【茶包射手筆記】清除 Windows TCP Port 保留區段-黑暗執行緒 遇到老問題,Visual Studio 啟動 IISExpress 跑 ASP.NET Core 時冒出 Failed to register URL "http://local...
-
5
【茶包射手筆記】gacutil 坑人記 2021-04-27 09:58 PM
-
6
【茶包射手筆記】網路資料夾因 Thumbs.db 鎖定無法刪除-黑暗執行緒 在 Windows 刪除網路資料夾目錄時偶爾會遇到 Thumbs.db 被檔案總管鎖定造成無法刪除: Thumbs.db 是 Windows 用來儲存照片、影片縮圖的系統檔案,以前會散落在包含圖片、影片的資...
-
13
【茶包射手筆記】Chrome 莫名佔用 CPU 2021-07-17 10:40 AM 0 1,531 Windows 剛重新開機,登入先開好 Chrome 準備 Google 爬文,還在想關鍵...
-
12
【茶包射手筆記】Git 無法建立 .git/index.lock 錯誤-黑暗執行緒同事遇到一個 Git 錯誤,印象裡我有遇過,原本信心滿滿準備找出 KB 文章秒殺它,卻發現上回沒寫筆記。幸好還記得原因跟解法,補上筆記。 錯誤會發生 Cmder 下 Git 指令或使用軟體執行 Git...
-
8
【茶包射手筆記】AD Domain Controller 出現某主機的本機帳號登入錯誤-黑暗執行緒 又一則奇怪的 4625 登入失敗稽核事件案例 - 在 AD 網域 Domain Controller 上出現某台機器「本機使用者帳號」登入失敗記錄。 情境說明如下。 出場角色有三位,...
-
6
【茶包射手筆記】PowerShell Invoke-WebRequest IE 錯誤-黑暗執行緒 某段 Invoke-WebRequest 指令開發測試完,部署到目的主機,經手動執行確認 OK,設成排程卻出現以下錯誤訊息: The response content cannot be parsed because th...
-
5
【茶包射手筆記】.NET 專案參照看似一切正常,卻無法編譯-黑暗執行緒 因為一個 .NET 參照問題鬼打牆十分鐘,脫身後想起好像不是第一次遇到,肯定是當時沒好好寫篇筆記才被詛咒,趕緊補上。 模擬出相似情境如下,UnitTest...
-
2
【茶包射手筆記】F12 偵錯導致 window.open() 快顯封鎖-黑暗執行緒 現代瀏覽器對 window.open() 行為有諸多限制,以防止其被濫用。瀏覽器多內建有快顯封鎖器 (Popu...
-
4
【茶包射手筆記】Hyper-V 虛擬交換器導致主機網路爆慢-黑暗執行緒 開始在新工作機上裝 Hyper-V VM,準備考驗它的能耐,才小試一下,便有很深的感觸。...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK