【问题标题】:DateTime timezone in .NET seems to be wrong?.NET 中的 DateTime 时区似乎是错误的?
【发布时间】:2018-06-14 16:55:02
【问题描述】:

我从 .NET MVC 中的字符串解析 DateTime 获得了一些乐趣,并且我发现了一些奇怪的行为。看看这个测试:

[Test]
public void DoesItWork()
{
    DateTime theTime = DateTime.Now;
    DateTime theUTCTime = theTime.ToUniversalTime();
    Assert.IsTrue(theTime==theUTCTime);         
}

我现在在英国,而且是英国夏令时,所以我预计 UTC 时间会比 DateTime.Now 的值晚一个小时。就是这样。但是当我在我的初始日期时间调用.ToUniversalTime() 并减去一个小时时,该值的 Kind 属性也会更新 - 从 Local 到 Utc。这也是我所期望的。

但是当我来比较这两个DateTimevariables 的值时,相等运算符没有考虑不同的 Kind 值,而只是报告它们是不同的值。对我来说,这似乎完全错误。

谁能解释为什么它会这样工作?

【问题讨论】:

  • 因为documented是这样的? “如果它们的 Ticks 属性值相等,则当前实例和值相等。在相等性测试中不考虑它们的 Kind 属性值。”
  • 您是否断言对象属于日期时间?如果您比较 theTime.Kind,您会期待什么?有一种称为 TimeZoneInfo 的类型可以为您提供日期计算。
  • 对于信息,DateTimeOffset 的行为方式相同(即具有相同 UTC 的两个“不同”DateTimeOffset 被认为是相等的),所以你在那里也好不到哪里去。 NUnit 允许您在 DateTimeOffsets 上的 IsEqual 约束上指定 WithSameOffset 以使比较包括偏移量。您可以为 DateTimes 执行 WithSameKind,如 NUnit issue 196 所示(接近该页面的末尾)

标签: c# .net datetime datetime-format


【解决方案1】:

根据MSDNMSDN2比较两个DateTime值:

备注 为了确定当前实例与值的关系,CompareTo 方法将当前实例的 Ticks 属性与值进行比较,但忽略它们的 Kind 属性。在比较 DateTime 对象之前,请确保对象代表同一时区的时间。您可以通过比较它们的 Kind 属性的值来做到这一点。

备注 Equality 运算符通过比较它们的刻度数来确定两个 DateTime 值是否相等。在比较 DateTime 对象之前,请确保对象代表同一时区的时间。您可以通过比较它们的 Kind 属性的值来做到这一点。

所以它是正确的。

链接到DateTime.Kind Property 并再次从备注:

Kind 属性允许 DateTime 值清楚地反映协调世界时 (UTC) 或本地时间。相比之下,DateTimeOffset 结构可以明确地将任何时区中的任何时间反映为单个时间点。

更新

关于您的评论。恕我直言,这是预期的行为。因为通常,您不需要比较来自不同时区的两个 DateTime。如果你需要这样做,你必须使用 DateTimeOffset DateTimeOffset Structure 这是:

备注 DateTimeOffset 结构包括一个 DateTime 值以及一个 Offset 属性,该属性定义当前 DateTimeOffset 实例的日期和时间与协调世界时 (UTC) 之间的差异。因为它准确地定义了相对于 UTC 的日期和时间,DateTimeOffset 结构不像 DateTime 结构那样包含 Kind 成员。它表示日期和时间,其 UTC 范围从 0001 年 1 月 1 日午夜 12:00:00 到公元 9999 年 12 月 31 日晚上 11:59:59。

【讨论】:

  • 嗯,是的,我同意按照您的描述记录它。你不认为这在逻辑上是错误的吗?如果您要包含一个 Kind 实例属性,那么它肯定应该是比较的一部分 - 或者如果不是,那么会有一个不这样做的原因。
猜你喜欢
  • 2021-08-16
  • 2019-03-26
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 2019-08-19
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多