Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 安全地比较本地和通用日期时间_C#_.net_.net 4.0_Datetime Comparison - Fatal编程技术网

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

C# 安全地比较本地和通用日期时间,c#,.net,.net-4.0,datetime-comparison,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 如果一个是DateTimeKind.Local,另一个是DateTimeKind.UTC,则DateTimes上的所有比较操作似乎都无法执行任何类型

我刚刚注意到DateTime比较中的一个荒谬缺陷

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

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

如果一个是DateTimeKind.Local,另一个是DateTimeKind.UTC,则DateTimes上的所有比较操作似乎都无法执行任何类型的智能转换。除了始终将比较中涉及的日期时间和时间转换为utc时间之外,可靠地比较日期时间是否是更好的方法?

经过编辑,我最初的答案部分不正确:

调用
.Equal
.Compare
时,会在内部比较值
.InternalTicks
。这个字段是不相等的,因为它被调整了几个小时以表示世界时间中的时间。您应该这样看:DateTime对象表示未命名时区中的时间,但不是universal time plus时区。时区可以是本地(系统的时区)或UTC。您可能会认为这是缺少DATETIME类。

当转换到另一个时区时,时间是——并且应该——调整的。这可能就是为什么Microsoft选择使用方法而不是属性,以强调转换为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对象(我们称之为SmartDateTime),它包含日期时间和时区。在使用原始日期时间操作符进行比较之前,我覆盖所有操作符,如==并比较并转换为UTC。

为什么不将所有日期都设置为UTC?对于与之关联的业务对象,它们将始终为UTC。然而,在整个应用程序的其他地方,当在一个特定的业务对象上使用日期字段时,我必须记住转换为utc时间。这是一个令人讨厌的、难以发现的bug的来源,特别是如果你在一个等于utc的本地时区开发,发现您的产品在发货时或夏时制开始时出现故障。我认为这个故事的寓意是,您应该在应用程序中的任何地方使用任何数据的标准格式(Unicode字符串、UTC日期等)。我支持您对这一荒谬缺陷的看法。MSDN文章()指出DateTime:“表示时间上的一个瞬间,通常表示为一天中的一个日期和时间。”文章作者似乎同意您和我关于这应该如何工作的看法。实施似乎失败了。这就是我计划要做的。最糟糕的是,它与linq to sql绑定,因此我必须将现有的datetime字段设置为私有,并公开我的自定义类的实例,该实例将持久保持为私有datetime…谈谈uglyUgh。您最好在数据库中添加一个TimeZoneInfo字段,并将日期全部存储在UTC中。这就是我一直在做的,只是需要转换任何数据库中使用的每个日期时间有点糟糕comparison@jdc0589:我原来的回答不正确,我更新了它以反映实际的内部情况。有人能为DateTime证明这种行为吗?我想我就是不明白。为什么直接比较不能解释时区?这对我来说似乎有缺陷,我认为这是一个错误