当时钟转向夏时制时,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对象必须具有相同的时区,但在这种情况下,结果似乎仍然与我当前的理解不正确。
发布于 2022-03-02 19:44:14
首先,请注意,您发布的代码不会为其他时区的人重现问题,因为DST是在不同的时间开始的(如果发生了)。
第二,要注意的是,您所开始的字符串表示时间上的时刻,而DateTime只捕获三条信息*
由于“本地”类不包含任何有关日期所在位置的信息,因此将时间转换为DateTimes是一种有损操作:您正在丢失无法稍后检索的重要数据。
这意味着被翻译成29/10/2023 01:00:00的两个条目彼此之间完全无法区分。它们都小于29/10/2023 01:30:00:你不可能有一个比那个时间更好,而另一个比它更短。如果您问框架(如果其中一个日期是IsDaylightSavingTime() ),它只会根据它所拥有的信息告诉您它的最佳猜测:它无法区分在DST切换之前发生的1AM与在DST切换之后发生的1AM之间的区别。
解决方案是将您的字符串转换为一种精确捕捉时间瞬间的类型。它的内置类是DateTimeOffset。通常情况下,在代表时间点的任何时候使用这种类型都是明智的,而不是用户选择的日期和时间。当向用户显示时间戳时,可以根据用户的位置设置轻松地将该值转换回本地化时间。
如果您需要更多的灵活性,NodaTime库包括几个更精细的类,比如Instant,它们适合在各种特殊情况下使用。
*这并不是完全正确的: DateTime可以在内部保存更多的数据(参见下面的注释)。该数据用于将时间转换回UTC,但不是用于比较两个DateTimes的值,因此这个答案的其余部分基本上仍然正确。
https://stackoverflow.com/questions/71326988
复制相似问题