The following console program in C# illustrates the issue. See also the Actual vs. Expected results.
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
static class Program
{
static void Main()
{
DisplaySerialization(new DateTime(2012, 1, 1, 0, 0, 0, DateTimeKind.Utc));
DisplaySerialization(new DateTime(2012, 1, 1, 0, 0, 0, DateTimeKind.Local));
DisplaySerialization(new DateTime(2012, 1, 1, 0, 0, 0, DateTimeKind.Unspecified));
Console.WriteLine();
DisplayDeserialization(@"""\/Date(1325376000000)\/""");
DisplayDeserialization(@"""\/Date(1325376000000+0000)\/""");
DisplayDeserialization(@"""\/Date(1325376000000-0000)\/""");
DisplayDeserialization(@"""\/Date(1325376000000-0700)\/""");
DisplayDeserialization(@"""\/Date(1325376000000-0500)\/""");
DisplayDeserialization(@"""\/Date(1325376000000+BLAH)\/""");
Console.ReadLine();
}
static void DisplaySerialization(DateTime dateTime)
{
var input = string.Format("{0:o} ({1})", dateTime, dateTime.Kind);
var output = dateTime.ToJson();
Console.WriteLine("{0} => {1}", input.PadRight(41), output);
}
static void DisplayDeserialization(string input)
{
var dateTime = input.FromJson<DateTime>();
var output = string.Format("{0:o} ({1})", dateTime, dateTime.Kind);
Console.WriteLine("{0} => {1}", input.PadRight(30), output);
}
static string ToJson(this object obj)
{
using (var ms = new MemoryStream())
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
var ser = new DataContractJsonSerializer(obj.GetType());
ser.WriteObject(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
return reader.ReadToEnd();
}
}
static T FromJson<T>(this string json)
{
var bytes = Encoding.UTF8.GetBytes(json);
using (var ms = new MemoryStream(bytes))
{
var ser = new DataContractJsonSerializer(typeof(T));
return (T)ser.ReadObject(ms);
}
}
}
2012-01-01T00:00:00.0000000Z (Utc) => "\/Date(1325376000000)\/"
2012-01-01T00:00:00.0000000-07:00 (Local) => "\/Date(1325401200000-0700)\/"
2012-01-01T00:00:00.0000000 (Unspecified) => "\/Date(1325401200000-0700)\/"
"\/Date(1325376000000)\/" => 2012-01-01T00:00:00.0000000Z (Utc)
"\/Date(1325376000000+0000)\/" => 2011-12-31T17:00:00.0000000-07:00 (Local)
"\/Date(1325376000000-0000)\/" => 2011-12-31T17:00:00.0000000-07:00 (Local)
"\/Date(1325376000000-0700)\/" => 2011-12-31T17:00:00.0000000-07:00 (Local)
"\/Date(1325376000000-0500)\/" => 2011-12-31T17:00:00.0000000-07:00 (Local)
"\/Date(1325376000000+BLAH)\/" => 2011-12-31T17:00:00.0000000-07:00 (Local)
2012-01-01T00:00:00.0000000Z (Utc) => "\/Date(1325376000000)\/"
2012-01-01T00:00:00.0000000-07:00 (Local) => "\/Date(1325401200000-0700)\/"
2012-01-01T00:00:00.0000000 (Unspecified) => "\/Date(1325401200000+????)\/"
"\/Date(1325376000000)\/" => 2012-01-01T00:00:00.0000000 (Utc)
"\/Date(1325376000000+0000)\/" => 2012-01-01T00:00:00.0000000Z (Unspecified)
"\/Date(1325376000000-0000)\/" => 2012-01-01T00:00:00.0000000Z (Unspecified)
"\/Date(1325376000000-0700)\/" => 2011-12-31T17:00:00.0000000-07:00 (Unspecified)
"\/Date(1325376000000-0500)\/" => 2011-12-31T19:00:00.0000000-05:00 (Unspecified)
"\/Date(1325376000000+BLAH)\/" => (an exception should be thrown)