默認情況下,當時鐘轉向夏令時時,似乎 DateTime 物件的比較不起作用。我的最終目標是檢查時間串列是否按升序排列。我有以下代碼來證明我的問題:(我住在英國)
// Create a list of strings
List<string> timeStrings = new List<string>
{
"2023-10-29 00:00:00.000 00:00",
"2023-10-29 00:30:00.000 00:00",
"2023-10-29 01:00:00.000 00:00",
"2023-10-29 01:30:00.000 00:00",
"2023-10-29 02:00:00.000 00:00",
};
// Convert to a list of DateTimes
List<DateTime> times = new List<DateTime>();
foreach (string str in timeStrings)
{
DateTime dateTime;
DateTime.TryParseExact(str, "yyyy-MM-dd HH:mm:ss.FFF zzz", null, DateTimeStyles.None, out dateTime);
times.Add(dateTime);
}
// Print the results
for (int i = 0; i < times.Count; i )
{
string timeString = timeStrings[i];
DateTime time = times[i];
Console.WriteLine(timeString " -> " time.ToString());
if (i < times.Count - 1)
{
Console.WriteLine(times[i] < times[i 1] ? "/\\" : "\\/");
}
}
此代碼的輸出顯示此排序(\/表示頂部更大):
2023-10-29 00:00:00.000 00:00 -> 29/10/2023 01:00:00
/\
2023-10-29 00:30:00.000 00:00 -> 29/10/2023 01:30:00
\/
2023-10-29 01:00:00.000 00:00 -> 29/10/2023 01:00:00
/\
2023-10-29 01:30:00.000 00:00 -> 29/10/2023 01:30:00
/\
2023-10-29 02:00:00.000 00:00 -> 29/10/2023 02:00:00
奇怪的是,當我.ToUniversalTime()在比較之前轉換時間時,我得到了我想要的順序。這意味著確定真實順序的所有資訊都在 DateTime 物件中。
當我閱讀檔案時,我只能發現比較的 DateTime 物件必須具有相同的時區,但在這種情況下它們確實如此,并且結果似乎仍然與我目前的理解不正確。
uj5u.com熱心網友回復:
首先,請注意,您發布的代碼不會為其他時區的人重現該問題,因為 DST 對他們來說在不同的時間開始(如果它發生的話)。
其次,請注意,您開始使用的字串表示時間點,而 DateTime 僅捕獲三條資訊*:
- 日歷日期
- 一天中的某個時間(掛鐘)
- “種類”:UTC、本地或未知
由于 Kind 上的“本地”不包含有關該日期本地位置的任何資訊,因此將您的時刻轉換為 DateTimes 是一項有損操作:您正在丟失以后無法檢索的重要資料。
這意味著被翻譯成的兩個條目29/10/2023 01:00:00彼此完全無法區分。它們都小于29/10/2023 01:30:00:你不能讓一個大于那個時間而另一個小于那個時間。如果您詢問框架是否是這些日期之一IsDaylightSavingTime(),它只會根據它所擁有的資訊告訴您它的最佳猜測:它無法區分 DST 切換之前發生的 1 AM 和 DST 之后發生的 1 AM 之間的區別轉變。
解決方案是將您的字串轉換為準確捕捉某個時刻的型別。內置類是DateTimeOffset. 在表示時間點而不是用戶選擇的日期和時間時,通常使用這種型別是明智的。在向用戶顯示時間戳時,您可以根據用戶的位置設定輕松將該值轉換回本地化時間。
如果您需要更大的靈活性,NodaTime 庫包括幾個更細微的類,例如Instant,它們適合在各種特殊情況下使用。
*這并不完全正確:DateTime 可以在內部保留更多資料(請參閱下面的評論)。該資料用于將時間轉換回 UTC,但不用于比較兩個 DateTimes 的值,因此該答案的其余部分仍然基本正確。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/436868.html
