web-dev-qa-db-ja.com

DateTime.ParseがUTC日付を解析できないのはなぜですか

理由これを解析できません:

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

「UTC」は有効なタイムゾーン指定子ではないため、この文字列を解析できません。

UTC時間は、時間文字列の末尾に「Z」を追加することで示されるため、解析コードは次のようになります。

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

ISO 8601に関するウィキペディアの記事

時刻がUTCの場合、スペースなしで時刻の直後に「Z」を追加します。 「Z」は、ゼロUTCオフセットのゾーン指定子です。したがって、「09:30 UTC」は「09:30Z」または「0930Z」として表されます。 「14:45:15 UTC」は「14:45:15Z」または「144515Z」になります。

UTC時間は「Zulu」時間としても知られています。「Zulu」はNATOの「Z」を表す音声アルファベットの単語であるためです。

70
Simon P Stevens

日付時刻に「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時間に変換します。

43
David Thielen

次の形式を指定する必要があります。

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

それを使用するだけです:

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/

役に立てば幸いです。

またはへの呼び出しでAdjustToUniversal DateTimeStyleを使用します

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

質問で指定された文字列を変更せずに正しく解析するには、次を使用します。

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パラメーターは、指定された文字列が協定世界時の文字列であることを指定するために使用されます。

9
satbot

有効な形式ではありませんが、「火、2008年1月1日00:00:00 GMT」です。

ドキュメントには次のように書かれています:

タイムゾーン情報を含み、ISO 8601に準拠する文字列。たとえば、次の2つの文字列の最初の文字列は協定世界時(UTC)を示します。 2番目は、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
HackerBaloo

ここに示したすべてのヒントに加えて、さらにいくつかを使用するユーティリティメソッドをまとめました。

    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バックエンドに供給される最も一般的に見られる日付文字列形式を解析する方法を示す2番目のユーティリティメソッドも含めました。楽しい。

1
XDS

「UTC」を「GMT」に置き換えるだけです-シンプルで、正しくフォーマットされた日付を壊しません:

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