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

时间:2009-11-18 15:06:43

标签: c# datetime parsing

为什么无法解析这个:

DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC")

10 个答案:

答案 0 :(得分:68)

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

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

DateTime.Parse("Tue, 1 Jan 2008 00:00:00Z");

来自Wikipedia article on ISO 8601

  

如果时间是UTC,请添加'Z'   没有一个时间后直接   空间。 'Z'是区域指示符   零UTC偏移。 “09:30 UTC”是   因此表示为“09:30Z”或   “0930Z”。 “14:45:15 UTC”将是   “14:45:15Z”或“144515Z”。

     

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

答案 1 :(得分:40)

假设您使用格式" 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时间。

答案 2 :(得分:16)

您需要指定格式:

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

答案 3 :(得分:12)

或在调用

时使用AdjustToUniversal DateTimeStyle
DateTime.ParseExact(String, String[], IFormatProvider, DateTimeStyles)

答案 4 :(得分:12)

只需使用:

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!");
}

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

http://rextester.com/

我希望它有所帮助。

答案 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);

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

答案 6 :(得分: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

答案 7 :(得分:0)

只需替换" UTC"用" GMT" - 简单且没有正确格式化日期:

DateTime.Parse("Tue, 1 Jan 2008 00:00:00 UTC".Replace("UTC", "GMT"))

答案 8 :(得分:0)

我整理了一个实用程序方法,该方法使用了此处显示的所有提示以及更多内容:

    static private readonly string[] MostCommonDateStringFormatsFromWeb = {
        "yyyy'-'MM'-'dd'T'hh:mm:ssZ",  //     momentjs aka universal sortable with 'T'     2008-04-10T06:30:00Z          this is default format employed by moment().utc().format()
        "yyyy'-'MM'-'dd'T'hh:mm:ss.fffZ", //  syncfusion                                   2008-04-10T06:30:00.000Z      retarded string format for dates that syncfusion libs churn out when invoked by ejgrid for odata filtering and so on
        "O", //                               iso8601                                      2008-04-10T06:30:00.0000000
        "s", //                               sortable                                     2008-04-10T06:30:00
        "u"  //                               universal sortable                           2008-04-10 06:30:00Z
    };

    static public bool TryParseWebDateStringExactToUTC(
        out DateTime date,
        string input,
        string[] formats = null,
        DateTimeStyles? styles = null,
        IFormatProvider formatProvider = null
    )
    {
        formats = formats ?? MostCommonDateStringFormatsFromWeb;
        return TryParseDateStringExactToUTC(out date, input, formats, styles, formatProvider);
    }

    static public bool TryParseDateStringExactToUTC(
        out DateTime date,
        string input,
        string[] formats = null,
        DateTimeStyles? styles = null,
        IFormatProvider formatProvider = null
    )
    {
        styles = styles ?? DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal; //0 utc
        formatProvider = formatProvider ?? CultureInfo.InvariantCulture;

        var verdict = DateTime.TryParseExact(input, result: out date, style: styles.Value, formats: formats, provider: formatProvider);
        if (verdict && date.Kind == DateTimeKind.Local) //1
        {
            date = date.ToUniversalTime();
        }

        return verdict;

        //0 employing adjusttouniversal is vital in order for the resulting date to be in utc when the 'Z' flag is employed at the end of the input string
        //  like for instance in   2008-04-10T06:30.000Z
        //1 local should never happen with the default settings but it can happen when settings get overriden   we want to forcibly return utc though
    }

注意使用“-”和“ T”(单引号)。这是最佳做法,因为区域设置会干扰字符的解释,例如“-”,导致将其解释为“ /”或“。”。或您的区域设置表示为date-components-separator的任何内容。我还包括了第二种实用程序方法,该方法演示了如何解析从Web客户端提供给rest-api后端的最常见的日期字符串格式。享受。

答案 9 :(得分:-4)

不确定原因,但您可以在try / catch中包装DateTime.ToUniversalTime,并在更多代码中实现相同的结果。

祝你好运。