Просмотр исходного кода

fixing DateTime serialization

svn path=/trunk/mcs/; revision=82988
Konstantin Triger 18 лет назад
Родитель
Сommit
3baf413bb9

+ 6 - 6
mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JSON/JavaScriptConvert.cs

@@ -65,8 +65,8 @@ namespace Newtonsoft.Json
 			Null = "null";
 			Undefined = "undefined";
 
-			InitialJavaScriptDateTicks = (new DateTime(1970, 1, 1)).Ticks;
-			MinimumJavaScriptDate = new DateTime(100, 1, 1);
+			InitialJavaScriptDateTicks = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
+			MinimumJavaScriptDate = new DateTime (100, 1, 1, 0, 0, 0, DateTimeKind.Utc);
 		}
 
 		/// <summary>
@@ -78,11 +78,13 @@ namespace Newtonsoft.Json
 		{
 			long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value);
 
-			return "new Date(" + javaScriptTicks + ")";
+			return @"""\/Date(" + javaScriptTicks + @")\/""";
 		}
 
 		internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
 		{
+			dateTime = dateTime.ToUniversalTime ();
+
 			if (dateTime < MinimumJavaScriptDate)
 				dateTime = MinimumJavaScriptDate;
 
@@ -93,9 +95,7 @@ namespace Newtonsoft.Json
 
 		internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
 		{
-			DateTime dateTime = new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks);
-
-			return dateTime;
+			return new DateTime((javaScriptTicks * 10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc);
 		}
 
 		/// <summary>

+ 13 - 0
mcs/class/System.Web.Extensions/System.Web.Script.Serialization/JSON/JsonReader.cs

@@ -520,6 +520,19 @@ namespace Newtonsoft.Json
 					case '"':
 					case '\'':
 						ParseString(_currentChar);
+						string value = (string)Value;
+						try {
+							if (value != null && value.Length > 8 &&
+								value.StartsWith (@"/Date(", StringComparison.Ordinal) &&
+								value.EndsWith (@")/", StringComparison.Ordinal)) {
+								long javaScriptTicks = Convert.ToInt64 (value.Substring (6, value.Length - 8));
+
+								DateTime date = JavaScriptConvert.ConvertJavaScriptTicksToDateTime (javaScriptTicks);
+
+								SetToken (JsonToken.Date, date);
+							}
+						}
+						catch { /* if failed - leave string */ }
 						return true;
 					case 't':
 						ParseTrue();

+ 19 - 2
mcs/class/System.Web.Extensions/Test/System.Web.Script.Serialization/JavaScriptSerializerTest.cs

@@ -38,6 +38,7 @@ using System.Drawing;
 using ComponentModel = System.ComponentModel;
 using System.Globalization;
 using System.Threading;
+using System.Text.RegularExpressions;
 
 
 namespace Tests.System.Web.Script.Serialization
@@ -49,14 +50,14 @@ namespace Tests.System.Web.Script.Serialization
 		{
 			//public DateTime dt;
 			//public DateTime dt1;
-			public DateTime dt2;
+			//public DateTime dt2;
 			public bool bb;
 			//Hashtable hash;
 
 			public void Init() {
 				//dt = DateTime.MaxValue;
 				//dt1 = DateTime.MinValue;
-				dt2 = new DateTime ((DateTime.Now.Ticks / 10000) * 10000);
+				//dt2 = new DateTime ((DateTime.Now.Ticks / 10000) * 10000);
 				bb = true;
 				//hash = new Hashtable ();
 				//hash.Add ("mykey", 1);
@@ -389,6 +390,22 @@ namespace Tests.System.Web.Script.Serialization
 			ser.Serialize ("aaa", null);
 		}
 
+		static readonly long InitialJavaScriptDateTicks = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
+
+		[Test]
+		public void TestSerializeDate () {
+			JavaScriptSerializer ser = new JavaScriptSerializer ();
+			DateTime now = new DateTime (633213894056010000L);
+
+			string actual = ser.Serialize (now);
+			DateTime dateTime = now.ToUniversalTime ();
+			long javaScriptTicks = (dateTime.Ticks - InitialJavaScriptDateTicks) / (long) 10000;
+
+			object dd = ser.DeserializeObject (@"""\/Datte(" + javaScriptTicks + @")\/""");
+			Assert.AreEqual (@"""\/Date(" + javaScriptTicks + @")\/""", actual);
+			Assert.AreEqual (now.ToUniversalTime(), ser.DeserializeObject (actual));
+		}
+
 		class MyJavaScriptConverter : JavaScriptConverter
 		{
 			public override object Deserialize (IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {