Given a DateTime object, how do I get an ISO 8601 date in string format?

后端 未结 18 2212
暖寄归人
暖寄归人 2020-11-22 02:15

Given:

DateTime.UtcNow

How do I get a string which represents the same value in an ISO 8601-compliant format?

Note that ISO 8601 de

相关标签:
18条回答
  • 2020-11-22 02:19
    System.DateTime.UtcNow.ToString("o")
    

    =>

    val it : string = "2013-10-13T13:03:50.2950037Z"
    
    0 讨论(0)
  • 2020-11-22 02:19

    You have a few options including the "Round-trip ("O") format specifier".

    var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
    Console.WriteLine(date1.ToString("O"));
    Console.WriteLine(date1.ToString("s", System.Globalization.CultureInfo.InvariantCulture));
    

    Output

    2008-03-01T07:00:00.0000000
    2008-03-01T07:00:00
    

    However, DateTime + TimeZone may present other problems as described in the blog post DateTime and DateTimeOffset in .NET: Good practices and common pitfalls:

    DateTime has countless traps in it that are designed to give your code bugs:

    1.- DateTime values with DateTimeKind.Unspecified are bad news.

    2.- DateTime doesn't care about UTC/Local when doing comparisons.

    3.- DateTime values are not aware of standard format strings.

    4.- Parsing a string that has a UTC marker with DateTime does not guarantee a UTC time.

    0 讨论(0)
  • 2020-11-22 02:19

    To convert DateTime.UtcNow to a string representation of yyyy-MM-ddTHH:mm:ssZ, you can use the ToString() method of the DateTime structure with a custom formatting string. When using custom format strings with a DateTime, it is important to remember that you need to escape your seperators using single quotes.

    The following will return the string represention you wanted:

    DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'", DateTimeFormatInfo.InvariantInfo)
    
    0 讨论(0)
  • 2020-11-22 02:22

    You can get the "Z" (ISO 8601 UTC) with the next code:

    Dim tmpDate As DateTime = New DateTime(Now.Ticks, DateTimeKind.Utc)
    Dim res as String = tmpDate.toString("o") '2009-06-15T13:45:30.0000000Z
    


    Here is why:

    The ISO 8601 have some different formats:

    DateTimeKind.Local

    2009-06-15T13:45:30.0000000-07:00
    

    DateTimeKind.Utc

    2009-06-15T13:45:30.0000000Z
    

    DateTimeKind.Unspecified

    2009-06-15T13:45:30.0000000
    


    .NET provides us with an enum with those options:

    '2009-06-15T13:45:30.0000000-07:00
    Dim strTmp1 As String = New DateTime(Now.Ticks, DateTimeKind.Local).ToString("o")
    
    '2009-06-15T13:45:30.0000000Z
    Dim strTmp2 As String = New DateTime(Now.Ticks, DateTimeKind.Utc).ToString("o")
    
    '2009-06-15T13:45:30.0000000
    Dim strTmp3 As String = New DateTime(Now.Ticks, DateTimeKind.Unspecified).ToString("o")
    

    Note: If you apply the Visual Studio 2008 "watch utility" to the toString("o") part you may get different results, I don't know if it's a bug, but in this case you have better results using a String variable if you're debugging.

    Source: Standard Date and Time Format Strings (MSDN)

    0 讨论(0)
  • 2020-11-22 02:26
    DateTime.UtcNow.ToString("s")
    

    Returns something like 2008-04-10T06:30:00

    UtcNow obviously returns a UTC time so there is no harm in:

    string.Concat(DateTime.UtcNow.ToString("s"), "Z")
    
    0 讨论(0)
  • 2020-11-22 02:27

    As mentioned in other answer, DateTime has issues by design.

    NodaTime

    I suggest to use NodaTime to manage date/time values:

    • Local time, date, datetime
    • Global time
    • Time with timezone
    • Period
    • Duration

    Formatting

    So, to create and format ZonedDateTime you can use the following code snippet:

    var instant1 = Instant.FromUtc(2020, 06, 29, 10, 15, 22);
    
    var utcZonedDateTime = new ZonedDateTime(instant1, DateTimeZone.Utc);
    utcZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
    // 2020-06-29T10:15:22Z
    
    
    var instant2 = Instant.FromDateTimeUtc(new DateTime(2020, 06, 29, 10, 15, 22, DateTimeKind.Utc));
    
    var amsterdamZonedDateTime = new ZonedDateTime(instant2, DateTimeZoneProviders.Tzdb["Europe/Amsterdam"]);
    amsterdamZonedDateTime.ToString("yyyy-MM-ddTHH:mm:ss'Z'", CultureInfo.InvariantCulture);
    // 2020-06-29T12:15:22Z
    
    

    For me NodaTime code looks quite verbose. But types are really useful. They help to handle date/time values correctly.

    Newtonsoft.Json

    To use NodaTime with Newtonsoft.Json you need to add reference to NodaTime.Serialization.JsonNet NuGet package and configure JSON options.

    services
        .AddMvc()
        .AddJsonOptions(options =>
        {
            var settings=options.SerializerSettings;
            settings.DateParseHandling = DateParseHandling.None;
            settings.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
        });
    
    0 讨论(0)
提交回复
热议问题