为什么DateTime.Parse无法解析UTC日期

Dve*_*Dve 59 c# datetime parsing

为什么不解析这个:

DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC")
Run Code Online (Sandbox Code Playgroud)

Sim*_*ens 71

它无法解析该字符串,因为"UTC"不是有效的时区指示符.

UTC时间通过在时间字符串的末尾添加"Z"来表示,因此您的解析代码应如下所示:

DateTime.Parse("Tue, 1 Jan 2008 00:00:00Z");
Run Code Online (Sandbox Code Playgroud)

来自维基百科关于ISO 8601的文章

如果时间是UTC,则在没有空格的时间之后直接添加"Z".'Z'是零UTC偏移的区域指示符.因此,"09:30 UTC"表示为"09:30Z"或"0930Z"."14:45:15 UTC"将是"14:45:15Z"或"144515Z".

UTC时间也被称为'Zulu'时间,因为'Zulu'是'Z'的北约语音字母词.

  • 正如其他答案所指出的那样,带有Z指示符的UTC日期字符串确实会成功_parsed_,但它也会被转换为本地时间,即它返回`Date`并带有`Kind`的`Local`和调整后的时间戳.要始终获得UTC`DateTime`,可以使用`DateTime.Parse("2008-01-01 00:00:00Z",CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal)中的一个,如@crokusek所示,或者`DateTimeOffset.Parse("2008-01-01 00:00:00Z").UtcDateTime`,正如@ruffin建议的那样. (38认同)
  • 奇怪的是,`DateTime.Parse("Tue, 1 Jan 2008 00:00:00Z").Kind` 返回的是`Local`,而不是`Utc`。 (3认同)

Dav*_*len 47

假设您使用格式"o"作为日期时间,因此您有"2016-07-24T18:47:36Z",有一种非常简单的方法来处理这个问题.

打电话DateTime.Parse("2016-07-24T18:47:36Z").ToUniversalTime().

当你打电话时会发生什么,你DateTime.Parse("2016-07-24T18:47:36Z")得到一个DateTime当地时区的设置.所以它将它转换为当地时间.

将其ToUniversalTime()更改为UTC DateTime并将其转换回UTC时间.


Dar*_*rov 17

您需要指定格式:

DateTime date = DateTime.ParseExact(
    "Tue, 1 Jan 2008 00:00:00 UTC", 
    "ddd, d MMM yyyy HH:mm:ss UTC", 
    CultureInfo.InvariantCulture);
Run Code Online (Sandbox Code Playgroud)

  • 很好的建议,但如果提供的日期字符串最后不包含UTC,则会失败.比如说你传递了一个结尾有+01的日期字符串,它会导致FormatException.取决于他想要做的事情. (2认同)

Ric*_*ves 16

只需使用:

var myDateUtc = DateTime.SpecifyKind(DateTime.Parse("Tue, 1 Jan 2008 00:00:00"), DateTimeKind.Utc);

if (myDateUtc.Kind == DateTimeKind.Utc)
{
     Console.WriteLine("Yes. I am UTC!");
}
Run Code Online (Sandbox Code Playgroud)

您可以使用在线c#编译器测试此代码:

http://rextester.com/

我希望它有所帮助.

  • 我实际上有点惊讶没有 `DateTime.Parse("Some:Time:here", "Utc")` 方法 (2认同)

小智 12

或者在调用时使用AdjustToUniversal DateTimeStyle

DateTime.ParseExact(String, String[], IFormatProvider, DateTimeStyles)
Run Code Online (Sandbox Code Playgroud)

  • 这个也适用,Utc输入和输出,没有格式,不需要Z:DateTime.Parse("8/3/2013 1:02:41 AM",CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal); (18认同)
  • 这实际上有效.我使用了这段代码并从UTC字符串得到了正确的UTC DateTime:DateTime.TryParseExact("2012-01-30T00:28:00Z","yyyy-MM-ddTHH:mm:ssZ",CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal,out TIMEVALUE)); (5认同)

小智 9

要正确解析问题中给出的字符串而不更改它,请使用以下命令:

using System.Globalization;

string dateString = "Tue, 1 Jan 2008 00:00:00 UTC";
DateTime parsedDate = DateTime.ParseExact(dateString, "ddd, d MMM yyyy hh:mm:ss UTC", CultureInfo.CurrentCulture, DateTimeStyles.AssumeUniversal);
Run Code Online (Sandbox Code Playgroud)

此实现使用字符串来指定要解析的日期字符串的确切格式.DateTimeStyles参数用于指定给定字符串是协调的通用时间字符串.

  • 根据[文档](https://learn.microsoft.com/en-us/dotnet/api/system.datetime.parseexact?view=netstandard-2.1),“返回的‘DateTime’的‘Kind’属性值为`DateTimeKind.Local`。” ParseExact 正确地将其解析为 UTC,但随后在返回之前将其转换为本地时间。如果您希望返回的值未经修改地返回为 UTC,请使用“DateTimeStyles.RoundtripKind”。 (2认同)

Hac*_*loo 7

这不是一个有效的格式,但是"星期二,2008年1月1日00:00:00 GMT"是.

文档说是这样的:

包含时区信息并符合ISO 8601的字符串.例如,以下两个字符串中的第一个指定协调世界时(UTC); 第二个指定比UTC早7个小时的时区:

2008-11-01T19:35:00.0000000Z

包含GMT指示符并符合RFC 1123时间格式的字符串.例如:

2008年11月1日星期六19:35:00 GMT

包含日期和时间以及时区偏移信息的字符串.例如:

03/01/2009 05:42:00 -5:00

  • 但是请注意,这会为我返回一个带有“本地”的“种类”的“日期时间”。看起来解决方法是使用 [DateTimeOffset.Parse](http://stackoverflow.com/a/14774345/1028230)(然后是 `x.UtcDateTime`),如果你想确保你没有脱离 UTC在您解析期间的货车。 (2认同)