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!
source to share
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
useK
- which conveys the right.Kind
, addingZ
to the exit toDateTimeKind.Utc
or offset from UTC toDateTimeKind.Local
or nothing at all forDateTimeKind.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, usefff
. Your use issss
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
usesUmAlQuraCalendar
, 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 hasDateTimeKind.Utc
.
source to share
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
source to share