问题
I'm trying to convert a DateTime object to a ISO8601 string but keep getting wrong results. I've looked around on stackoverflow, but couldn't find the right solution.
I start with a date time string of "2017-06-26T20:45:00.070Z" which 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 the convert that time back to it's original UTC format string to use it in another algorithm, but every conversion i try doesn't return it to that original string. Not sure what i'm doing wrong.
i've 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 to what js will do using toISOString() which is what i have listed in the newTime2 date time format, but it's not showing times either.
thanks!
回答1:
Observe:
// 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:
Don't use
Zin the format string. That's not a valid format specifier, so it is treated as just a character to output. It will be in every string, regardless of.Kindsetting of the input datetime.With
DateTime, useK- which properly conveys the.Kindby appending aZto the output forDateTimeKind.Utc, or an offset from UTC forDateTimeKind.Local, or nothing at all forDateTimeKind.Unspecified.Though
Twill output as a character because it's not a valid format specifier, I suggest always being explicit about those things, so prefer'T'.Using
fffwill always give you back three decimals (milliseconds). If you want the decimals omitted when zero, useFFFinstead. Your use ofsssis not valid.Passing
CultureInfo.InvariantCultureis a good practice, as it helps you avoid problems where the current culture might use a different calendar system. For examplear-SAuses theUmAlQuraCalendar, rather than the proleptic Gregorian calendar required by ISO 8601.In your code you tried, you had called
theTime.UtcNow- that won't compile.UtcNowis a static property, not an instance property.Also in your code you called
theTime.Date.ToUniveralTime()- Don't do that either..Datewill set the time components to zero, and.ToUniversalTime()will have no effect since the input value already hasDateTimeKind.Utc.
回答2:
The problem is that you are losing accuracy by using a cultural standard such as UTC or UniversalTime. If you just print 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 to not use any "culture". (For example, UniversalTime, or UtcNow). These cultural standards never include milliseconds ... because there is no culture where people really care all that often about milliseconds.
Solution:
var newTime = theTime.ToString("o");
Console.WriteLine(newTime);
2017-06-26T20:45:00.0700000Z
来源:https://stackoverflow.com/questions/44788305/c-sharp-convert-datetime-object-to-iso-8601-string