C# 为什么 DateTime.Parse 不能解析 UTC 日期

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1756639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 20:33:16  来源:igfitidea点击:

Why can't DateTime.Parse parse UTC date

c#datetimeparsing

提问by Dve

Whycan't it parse this:

为什么它不能解析这个:

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

采纳答案by Simon P Stevens

It can't parse that string because "UTC" is not a valid time zone designator.

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

UTC time is denoted by adding a 'Z' to the end of the time string, so your parsing code should look like this:

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

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

From the Wikipedia article on ISO 8601

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

If the time is in UTC, add a 'Z' directly after the time without a space. 'Z' is the zone designator for the zero UTC offset. "09:30 UTC" is therefore represented as "09:30Z" or "0930Z". "14:45:15 UTC" would be "14:45:15Z" or "144515Z".

UTC time is also known as 'Zulu' time, since 'Zulu' is the NATO phonetic alphabet word for 'Z'.

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

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

回答by Ian P

Not sure why, but you can wrap DateTime.ToUniversalTime in a try / catch and achieve the same result in more code.

不知道为什么,但是您可以在 try / catch 中包装 DateTime.ToUniversalTime 并在更多代码中实现相同的结果。

Good luck.

祝你好运。

回答by Darin Dimitrov

You need to specify the format:

您需要指定格式:

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

回答by user213809

or use the AdjustToUniversal DateTimeStyle in a call to

或在调用中使用 AdjustToUniversal DateTimeStyle

DateTime.ParseExact(String, String[], IFormatProvider, DateTimeStyles)

回答by HackerBaloo

It's not a valid format, however "Tue, 1 Jan 2008 00:00:00 GMT" is.

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

The documentation says like this:

文档是这样说的:

A string that includes time zone information and conforms to ISO 8601. For example, the first of the following two strings designates the Coordinated Universal Time (UTC); the second designates the time in a time zone seven hours earlier than UTC:

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

2008-11-01T19:35:00.0000000Z

2008-11-01T19:35:00.0000000Z

A string that includes the GMT designator and conforms to the RFC 1123 time format. For example:

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

Sat, 01 Nov 2008 19:35:00 GMT

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

A string that includes the date and time along with time zone offset information. For example:

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

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

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

回答by satbot

To correctly parse the string given in the question without changing it, use the following:

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

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

This implementation uses a string to specify the exact format of the date string that is being parsed. The DateTimeStyles parameter is used to specify that the given string is a coordinated universal time string.

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

回答by David Thielen

Assuming you use the format "o" for your datetime so you have "2016-07-24T18:47:36Z", there is a very simple way to handle this.

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

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

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

What happens when you call DateTime.Parse("2016-07-24T18:47:36Z")is you get a DateTimeset to the local timezone. So it converts it to the local time.

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

The ToUniversalTime()changes it to a UTC DateTimeand converts it back to UTC time.

将其ToUniversalTime()更改为 UTCDateTime并将其转换回 UTC 时间。

回答by Ricardo de Assuncao Goncalves

Just use that:

只需使用它:

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

You can test this code using the online c# compiler:

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

http://rextester.com/

http://rextester.com/

I hope it helps.

我希望它有帮助。

回答by Mike Godin

Just replace "UTC" with "GMT" -- simple and doesn't break correctly formatted dates:

只需将“UTC”替换为“GMT”——简单且不会破坏格式正确的日期:

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

回答by XDS

I've put together a utility method which employs all tips shown here plus some more:

我整理了一个实用方法,它采用了此处显示的所有技巧以及更多技巧:

    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
    }

Notice the use of '-' and 'T' (single-quoted). This is done as a matter of best practice since regional settings interfere with the interpretation of chars such as '-' causing it to be interpreted as '/' or '.' or whatever your regional settings denote as date-components-separator. I have also included a second utility method which show-cases how to parse most commonly seen date-string formats fed to rest-api backends from web clients. Enjoy.

请注意“-”和“T”(单引号)的使用。这是作为最佳实践完成的,因为区域设置会干扰诸如“-”之类的字符的解释,导致其被解释为“/”或“。”。或任何您的区域设置表示为日期组件分隔符。我还包含了第二个实用程序方法,它展示了如何解析从 Web 客户端提供给 rest-api 后端的最常见日期字符串格式。享受。