Home Dashboard Directory Help
Search

DataContractJsonSerializer does not properly handle DateTime values by mattj1856


Status: 

Closed
 as Deferred Help for as Deferred


4
0
Sign in
to vote
Type: Bug
ID: 723368
Opened: 2/4/2012 12:02:05 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
1
Workaround(s)
view
1
User(s) can reproduce this bug

Description

The DataContractJsonSerializer does not properly handle DateTime values. It blatantly disregards the precedent that has been established in the rest of .Net framework for proper use of the .Kind property.

More importantly, it completely disregards any offset passed in, choosing UTC if no offset, and Local time if ANY offset. This is very bad, because the offset and the date value are related, and ignoring the offset can provide the wrong date!

Serialization:

- A DateTime with a DateTimeKind.Local should be serialized to JSON with the local offset. This is working ok.

- A DateTime with a DateTimeKind.Utc should be serialized to JSON without an offset. This is working ok.

*** There should be some way to indicate how a DateTime with a DateTimeKind.Unspecified should be serialized to JSON. It currently assumes this is to be treated as local time, which might not be the case.

Deserialization:

- A JSON date without an offset should be treated as DateTimeKind.Utc. This is working ok.

*** A JSON date with an offset should be treated as DateTimeKind.Unspecified, and the provided offset should be applied. Instead, it is using as DateTimeKind.Local and applying the local offset.

*** A JSON date with an invalid offset (not in +HHMM or -HHMM form) should throw an exception. This is not occurring.

This should be raised as a critical issue. Anyone using the DataContractJsonSerializer for its intended use will run into these problems in any kind of global web application.
Details
Sign in to post a comment.
Posted by Microsoft on 2/6/2012 at 1:40 PM
Thanks for your feedback. We have a bug tracking fixing this in a future release - it is unlikely to happen for Dev11/.Net 4.5 though. Thanks.
Posted by mattj1856 on 2/6/2012 at 11:43 AM
After further research, I discovered that the "number of milliseconds since 1/1/1970" that is part of this format represents the "Unix Epoch" time, which is indeed in UTC. I therefore suggest that the current implementation of a timestamp without an offset be treated as UTC, where a timestamp of +0000 or -0000 should be "unspecified", as it might represent UTC, but might also represent London standard time (for example). I have update the bug and samples accordingly.

The remainder of the issues are as were originally stated. The biggest being that the presence of an offset is triggering local time without taking the offset into account.
Posted by MS-Moderator09 [Feedback Moderator] on 2/5/2012 at 6:02 PM
Thank you for submitting feedback on Visual Studio 2010 and .NET Framework. Your issue has been routed to the appropriate VS development team for review. We will contact you if we require any additional information.
Posted by MS-Moderator01 on 2/4/2012 at 12:45 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Posted by mattj1856 on 2/4/2012 at 12:29 PM
A separate, but related issue is that the DateTimeOffset class should serialize/deserialize to this same format, since the Offset is already there. Instead, it serializes to something like:

{"DateTime":"\/Date(1325401200000)\/","OffsetMinutes":-420}

Sign in to post a workaround.
Posted by mattj1856 on 2/8/2012 at 11:07 AM
Workaround - use a different serializer. ServiceStack.Text works well. The default option has this bug fixed as of version 3.4.4, and there is also an option to keep the bug in place for exact parity with DCJS. There's even an option to use ISO-8601 standard date formats (which is proabably a good idea). The options are set in ServiceStack.Text via the JsConfig.DateHandler property.

DCJS should really fix this bug though. Not everyone will be able to take a dependency on a third-party component.