考虑到时区,如何比较 DateTime 值?
How to compare DateTime values, taking into account timezone?
我有两个 DateTime
变量。每个都有一个存储在变量中的时区,这样当我 ToString
格式包括 zzz 我得到一个包括 +01:00
.
的字符串
在设计时我不知道时区是什么,我希望变量彼此具有不同的时区。
我想比较两个 DateTime
值,以便我知道哪个值更新。
例如,如果变量 A 为 2015-07-04T02:00:00+03:00
,变量 B 为 2015-07-03T18:00:00-07:00
,则 B > A.
我用 C# 写了什么来告诉我这个? (我不想使用第三方库。)
(致 SO 问题关闭狂热者:我已经花了几个小时使用 Google、MSDN 和 SO 对此进行了调查,我感到很困惑。我在 SO 上找不到与此非常相似的问题。我有信心这个问题的答案会对其他人有所帮助。)
你试过了吗?
var A = DateTime.Parse("2015-07-04T02:00:00+03:00");
var B = DateTime.Parse("2015-07-03T18:00:00-07:00");
Console.WriteLine( B > A );
你说:
I have two DateTime variables. Each has a timezone stored in the variable so that when I ToString with format including zzz I get a string including +01:00.
这是一个常见的误解。 DateTime
变量中没有存储时区。它只有一个 Kind
属性,类型为 DateTimeKind
,可以是 Utc
、Local
或 Unspecified
。
调用 ToString
时,zzz
格式说明符使用 Kind
属性 来确定要显示的偏移量。
当Kind
为DateTimeKind.Utc
时,偏移量总是+00:00
。
当 Kind
为 DateTimeKind.Local
时,偏移量由执行代码的计算机上的本地时区确定。例如,我的计算机设置为美国太平洋时间,因此偏移量将是 -08:00
或 -07:00
,具体取决于夏令时是否生效。
当 Kind
为 DateTimeKind.Unspecified
时,行为与 Local
相同。请记住,其他方法以不同的方式处理 Unspecified
- 这只是 zzz
说明符的特殊行为。
For this reason, the "zzz" format specifier is not recommended for use with DateTime
values.
回到你的问题:
At design time I do not know what the timezones will be and I am expecting the variables to have different timezones from each other.
那么你不能使用DateTime
。您应该改用 DateTimeOffset
,因为它保留了特定的时区偏移量,而不是使用 DateTimeKind
.
For example, if variable A is 2015-07-04T02:00:00+03:00 and variable B is 2015-07-03T18:00:00-07:00 then B > A. What do I write in C# to tell me this?
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
另请参阅:DateTime vs DatetimeOffset
此外
正如 Gustav 指出的那样,您 可以 使用 DateTime
,只要您在比较之前转换回世界时。这是由于 DateTime
's hidden fourth state (more here)。在解析期间正确设置状态,并在调用 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 );
结果:
A: 2015-11-01 08:00:00
B: 2015-11-01 09:00:00
True
False
如果您的本地时区设置为太平洋时间,您将获得上述结果。但是,如果它设置为其他值 - 您可能会得到 True
作为最后的结果,因为这些值可能已被解析为您所在时区的不同 local 时间,即使它们与太平洋时区的当地时间相同。
使用DateTimeOffset
更简单,转换次数少,不受当地时区影响。
我有两个 DateTime
变量。每个都有一个存储在变量中的时区,这样当我 ToString
格式包括 zzz 我得到一个包括 +01:00
.
在设计时我不知道时区是什么,我希望变量彼此具有不同的时区。
我想比较两个 DateTime
值,以便我知道哪个值更新。
例如,如果变量 A 为 2015-07-04T02:00:00+03:00
,变量 B 为 2015-07-03T18:00:00-07:00
,则 B > A.
我用 C# 写了什么来告诉我这个? (我不想使用第三方库。)
(致 SO 问题关闭狂热者:我已经花了几个小时使用 Google、MSDN 和 SO 对此进行了调查,我感到很困惑。我在 SO 上找不到与此非常相似的问题。我有信心这个问题的答案会对其他人有所帮助。)
你试过了吗?
var A = DateTime.Parse("2015-07-04T02:00:00+03:00");
var B = DateTime.Parse("2015-07-03T18:00:00-07:00");
Console.WriteLine( B > A );
你说:
I have two DateTime variables. Each has a timezone stored in the variable so that when I ToString with format including zzz I get a string including +01:00.
这是一个常见的误解。 DateTime
变量中没有存储时区。它只有一个 Kind
属性,类型为 DateTimeKind
,可以是 Utc
、Local
或 Unspecified
。
调用 ToString
时,zzz
格式说明符使用 Kind
属性 来确定要显示的偏移量。
当
Kind
为DateTimeKind.Utc
时,偏移量总是+00:00
。当
Kind
为DateTimeKind.Local
时,偏移量由执行代码的计算机上的本地时区确定。例如,我的计算机设置为美国太平洋时间,因此偏移量将是-08:00
或-07:00
,具体取决于夏令时是否生效。当
Kind
为DateTimeKind.Unspecified
时,行为与Local
相同。请记住,其他方法以不同的方式处理Unspecified
- 这只是zzz
说明符的特殊行为。
For this reason, the "zzz" format specifier is not recommended for use with
DateTime
values.
回到你的问题:
At design time I do not know what the timezones will be and I am expecting the variables to have different timezones from each other.
那么你不能使用DateTime
。您应该改用 DateTimeOffset
,因为它保留了特定的时区偏移量,而不是使用 DateTimeKind
.
For example, if variable A is 2015-07-04T02:00:00+03:00 and variable B is 2015-07-03T18:00:00-07:00 then B > A. What do I write in C# to tell me this?
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
另请参阅:DateTime vs DatetimeOffset
此外
正如 Gustav 指出的那样,您 可以 使用 DateTime
,只要您在比较之前转换回世界时。这是由于 DateTime
's hidden fourth state (more here)。在解析期间正确设置状态,并在调用 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 );
结果:
A: 2015-11-01 08:00:00
B: 2015-11-01 09:00:00
True
False
如果您的本地时区设置为太平洋时间,您将获得上述结果。但是,如果它设置为其他值 - 您可能会得到 True
作为最后的结果,因为这些值可能已被解析为您所在时区的不同 local 时间,即使它们与太平洋时区的当地时间相同。
使用DateTimeOffset
更简单,转换次数少,不受当地时区影响。