Reputation: 305
I've been using an old version of JSON.Net (4.0r4) for a while & have just updated to the latest one (4.5r11). I've noticed that dates used to be formatted like:
2013-03-20T09:00:00.119Z
but are now:
2013-03-20T09:00:00.119
The Z is missing at the end. According to Wikipedia:
If the time is in UTC, add a Z directly after the time without a space
This has broken a lot of my JavaScript code as I have a method that converts this into a DateTime
object & it expects the Z
. I can fix it by altering this function I use to do this & I've found out that I can
set the DateTimeZoneHandling
to DateTimeZoneHandling.Utc
but this means I would have to change a lot of C# code in multiple projects.
I'm just wondering why this has changed.
Thanks...
Upvotes: 23
Views: 26019
Reputation: 2478
If you have UTC data on server you should explicitly set DateTimeZoneHandling property
//serializer fix
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter()
{
SerializerSettings = new JsonSerializerSettings() {
ContractResolver=new CamelCasePropertyNamesContractResolver(),
DateTimeZoneHandling = DateTimeZoneHandling.Utc},
});
After this DateTime has "Z" at the end: 2017-05-11T00:35:20.8242381Z
Upvotes: 3
Reputation: 37987
What browser(s) are you seeing this occur in? Since the issue you're actually coping with is Javascript parsing, in my experience that problem is actually the millisecond rounding, not the presence of a Z or not.
Try this in IE9: http://jsfiddle.net/b9chris/HaBP8/
'2013-06-13T20:43:55.6',
'2013-06-13T20:43:55.61',
'2013-06-13T20:43:55.61Z',
'2013-06-13T20:43:55.611',
'2013-06-13T20:43:55.611Z'
In most browsers all dates parse fine; in IE9 the first 3 fail, regardless of a Z or no, because IE9 requires 3 places for the milliseconds number. The second 2 succeed, with and without the Z. What matters is 3 millisecond digits - the Z is irrelevant, including because Javascript does not contain a DateTimeKind like .Net does, so Z or no is irrelevant to how Javascript internalizes the date. Because the number of millisecond digits will sometimes be one or 2 depending on the time, if you're passing timestamps you'll get random-seeming failures.
I've reported this as a bug on the Json.Net Codeplex page; it was dismissed by the maintainer in the comments of the bug and closed. Go open source.
You can work around this bug using the code in this answer:
https://stackoverflow.com/a/15939945/176877
To be clear, the lack of a Z is incorrect on JSON.Net's part if it emits without it for DateTimeKind.UTC, but it is not an invalid ISO-8601 date more generally - no Z implicitly means Local Time:
http://en.wikipedia.org/wiki/ISO_8601#Times
If no UTC relation information is given with a time representation, the time is assumed to be in local time.
And as mentioned above Javascript's parsing doesn't care about the Z, so for your purposes, it doesn't matter.
Note also you might not actually be passing UTC to JSON.Net and triggering this issue. DateTime objects in C# can be of kind Local, Unspecified, or UTC. It's not fair to assume that DateTimes that aren't UTC are in fact UTC; passing it without timezone information is the safest bet. The .Net DateTime structure punts on timezones, so JSON.Net is left with no choice but to emit default DateTimes (DateTimeKind.Unspecified) as Local, barring integration with a .Net TimeZone library.
Upvotes: 6
Reputation: 11832
You can change how DateTime will be serialized, check this from JSON.NET author: Good (Date)Times with Json.NET
Upvotes: 4