考虑到时区,如何比较 DateTime 值?

cja*_*cja 5 c# timezone datetime

我有两个DateTime变量。每个都有一个时区存储在变量中,这样当我ToString使用包含 zzz 的格式时,我会得到一个包含+01:00.

在设计时,我不知道时区是什么,我希望变量具有彼此不同的时区。

我想比较这两个DateTime值,以便知道哪个值更新。

例如,如果变量 A 是2015-07-04T02:00:00+03:00变量 B2015-07-03T18:00:00-07:00则 B > A。

我用 C# 写什么来告诉我这个?(我不想使用第三方库。)

(对于 SO 问题结束狂热者:我花了几个小时使用 Google、MSDN 和 SO 对此进行了调查,但很困惑。我在 SO 上找不到与此非常相似的问题。我相信这个问题的答案会对其他人有所帮助。 )

Mat*_*int 7

你说:

我有两个 DateTime 变量。每个都有一个时区存储在变量中,这样当我 ToString 格式包括 zzz 时,我得到一个包括 +01:00 的字符串。

这是一个普遍的误解。 DateTime没有存储在变量中的时区。它只有一个Kind属性,它是类型的DateTimeKind,并且可以是UtcLocal,或Unspecified

调用时ToStringzzz格式说明符使用该Kind属性来确定要显示的偏移量。

  • Kind为 时DateTimeKind.Utc,偏移量始终为+00:00

  • Kind为 时DateTimeKind.Local,偏移量由执行代码的计算机上的本地时区确定。例如,我的电脑被设置为美国太平洋时间,因此偏移量可以是-08:00-07:00根据夏令时制是否有效与否。

  • Kind是时DateTimeKind.Unspecified,行为与它是一样的Local。请记住,其他方法Unspecified以不同的方式处理 - 这只是zzz说明符的特定行为。

MSDN 实际上说

因此,不建议将“zzz”格式说明符用于DateTime值。

回到你的问题:

在设计时,我不知道时区是什么,我希望变量具有彼此不同的时区。

那么你不能使用DateTime. 您应该改为使用DateTimeOffset,因为它保留了特定的时区偏移量而不是使用DateTimeKind.

例如,如果变量 A 是 2015-07-04T02:00:00+03:00 而变量 B 是 2015-07-03T18:00:00-07:00 那么 B > A。我用 C# 写什么来告诉我这个?

DateTimeOffset a = DateTimeOffset.Parse("2015-07-04T02:00:00+03:00");
DateTimeOffset b = DateTimeOffset.Parse("2015-07-03T18:00:00-07:00");

bool result = b > a;  // true
Run Code Online (Sandbox Code Playgroud)

另请参阅: DateTime 与 DatetimeOffset


此外

正如 Gustav 指出的那样,只要在比较之前转换回世界时,您就可以使用 just DateTime。这是由于DateTime隐藏的第四个状态更多在这里)而起作用。状态在解析过程中设置正确,并在ToUniversalTime调用时考虑。然后比较具有可操作的有效 UTC 时间。

DateTime A = DateTime.Parse("2015-11-01T01:00:00-07:00");
DateTime B = DateTime.Parse("2015-11-01T01:00:00-08:00");

Console.WriteLine(A.ToUniversalTime().ToString("'A: 'yyyy'-'MM'-'dd hh:mm:ss"));
Console.WriteLine(B.ToUniversalTime().ToString("'B: 'yyyy'-'MM'-'dd hh:mm:ss"));
Console.WriteLine( B.ToUniversalTime() > A.ToUniversalTime() );
Console.WriteLine( B > A );
Run Code Online (Sandbox Code Playgroud)

结果:

A: 2015-11-01 08:00:00
B: 2015-11-01 09:00:00
True
False
Run Code Online (Sandbox Code Playgroud)

如果您的本地时区设置为太平洋时间,您将获得上述结果。但是,如果它设置为其他内容 - 您可能会得到True最后一个结果,因为这些值可能已被解析为您所在时区的不同本地时间,即使它们在太平洋时区是相同的本地时间.

使用DateTimeOffset仍然更简单,转换次数更少,并且不受本地时区的影响。