C # convert datetime object to iso 8601 string

I am trying to convert a DateTime object to ISO8601 string but I am not getting the wrong results. I looked at stackoverflow but couldn't find the right solution.

I am starting with the date time string "2017-06-26T20: 45: 00.070Z" which is deserialized by newtonsoft from json and converted to a DateTime object in C #, equivalent to:

var theTime = new DateTime(2017, 6, 26, 20, 45, 00, 70, DateTimeKind.Utc);

      

Now I need to convert this time back to the original UTC string in order to use it in another algorithm, but every conversion I try does not return to the original string. Not sure what I am doing wrong.

I tried:

var newTime = theTime.UtcNow.ToString("o");
// returns "2017-06-26T00:00:00.0000000Z"

var newTime2 = theTime.Date.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.sssZ");
// returns "2017-06-26T00:00:00.00Z"

      

what am I doing wrong? I want the equivalent of what js will do using toISOString () which I listed in date format dateTime2 but it doesn't show the time either.

thank!

+3


source to share


2 answers


Note:

// Your input
DateTime dt = new DateTime(2017, 6, 26, 20, 45, 0, 70, DateTimeKind.Utc);

// ISO8601 with 7 decimal places
string s1 = dt.ToString("o", CultureInfo.InvariantCulture);
//=> "2017-06-26T20:45:00.0700000Z"

// ISO8601 with 3 decimal places
string s2 = dt.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", CultureInfo.InvariantCulture);
//=> "2017-06-26T20:45:00.070Z"

      



A few things:

  • Do not use Z

    in a format string. This is not a valid format specifier , so it is treated as only a character for output. It will be on every line regardless of the setting of the .Kind

    input datetime.

  • With the DateTime

    use K

    - which conveys the right .Kind

    , adding Z

    to the exit to DateTimeKind.Utc

    or offset from UTC to DateTimeKind.Local

    or nothing at all for DateTimeKind.Unspecified

    .

  • While it T

    will output as a character because it is not a valid format specifier, I suggest to always be explicit about these things, so prefer 'T'

    .

  • Using fff

    will always give you three decimal places (milliseconds). If you want decimals to be omitted at zero, use fff

    . Your use is sss

    invalid.

  • Transfer CultureInfo.InvariantCulture

    is good practice as it helps you avoid problems where the current culture might be using a different calendar system. For example, ar-SA

    uses UmAlQuraCalendar

    , rather than the pro-reptic Gregorian calendar required by ISO 8601.

  • In the code you tried, you called theTime.UtcNow

    -, which won't compile. UtcNow

    is a static property, not an instance property.

  • Also in your code you called theTime.Date.ToUniveralTime()

    - don't do this. .Date

    will set the time components to zero, and .ToUniversalTime()

    have no effect since the input value already has DateTimeKind.Utc

    .

+16


source


The problem is that you lose precision using a cultural standard like UTC

or UniversalTime

. If you just type your DateTime

:

var theTime = new DateTime(2017, 6, 26, 20, 45, 00, 70, 
    DateTimeKind.Utc);
Console.WriteLine(theTime);

      

6/26/2017 8:45:00 PM

You can read more about this issue here .



The solution is not to use any "culture". (For example, UniversalTime

or UtcNow

). These cultural standards never include milliseconds ... because there is no culture where people really care, which is often about a millisecond.

Decision:

var newTime = theTime.ToString("o");
Console.WriteLine(newTime);

      

2017-06-26T20: 45: 00.0700000Z

0


source







All Articles