安全地比较本地和通用日期时间

时间:2011-08-03 17:20:38

标签: c# .net .net-4.0 datetime-comparison

我刚注意到与DateTime比较似乎是一个荒谬的缺陷。

DateTime d = DateTime.Now;
DateTime dUtc = d.ToUniversalTime();

d == dUtc; // false
d.Equals(dUtc); //false
DateTime.Compare(d, dUtc) == 0; // false

似乎DateTimes上的所有比较操作都无法执行任何类型的智能转换(如果一个是DateTimeKind.Local,一个是DateTimeKind.UTC)。除了始终将比较中涉及的两者都转换为utc时间之外,这是一种更可靠地比较DateTimes的方法吗?

2 个答案:

答案 0 :(得分:43)

编辑,我的原始答案部分不正确:

当您致电.Equal.Compare时,会在内部比较值.InternalTicks。此字段是不等,因为它已经调整了几个小时来表示通用时间内的时间。您应该这样看:DateTime对象在未命名的时区中表示时间,但不是通用时间加时区。时区是Local(系统的时区)或UTC。您可能会认为缺少DateTime类。

转换到另一个时区时,时间是 - 并且应该 - 调整。这可能是微软选择使用方法而不是属性的原因,以强调转换为UTC时采取的操作。

最初我在这里写道,比较了结构,System.DateTime.Kind的标志是不同的。事实并非如此:它是不同的滴答数量:

t1.Ticks == t2.Ticks;       // false
t1.Ticks.Equals(t2.Ticks);  // false

要安全地比较两个日期,您可以将它们转换为相同的类型。如果您在比较之前将任何日期转换为通用时间,您将得到您所追求的结果:

DateTime t1 = DateTime.Now;
DateTime t2 = t1;
DateTime.Compare(t1.ToUniversalTime(), t2.ToUniversalTime());  // 0
DateTime.Equals(t1.ToUniversalTime(), t2.ToUniversalTime());  // true

道德:从不比较DateTime天真地

答案 1 :(得分:5)

为了解决这个问题,我创建了自己的DateTime对象(让我们称之为SmartDateTime),它包含DateTime和TimeZone。在使用原始DateTime运算符进行比较之前,我覆盖所有运算符,如==和比较并转换为UTC。