1 using System; 2 using System.Globalization; 3 using Newtonsoft.Json.Utilities; 4 5 namespace Newtonsoft.Json.Converters 6 { 7 /// <summary> 8 /// Converts a <see cref="DateTime"/> to and from a JavaScript date constructor (e.g. new Date(52231943)). 9 /// </summary> 10 public class JavaScriptDateTimeConverter : DateTimeConverterBase 11 { 12 /// <summary> 13 /// Writes the JSON representation of the object. 14 /// </summary> 15 /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param> 16 /// <param name="value">The value.</param> 17 /// <param name="serializer">The calling serializer.</param> WriteJson(JsonWriter writer, object value, JsonSerializer serializer)18 public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 19 { 20 long ticks; 21 22 if (value is DateTime) 23 { 24 DateTime dateTime = (DateTime)value; 25 DateTime utcDateTime = dateTime.ToUniversalTime(); 26 ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTime); 27 } 28 #if !PocketPC && !NET20 29 else if (value is DateTimeOffset) 30 { 31 DateTimeOffset dateTimeOffset = (DateTimeOffset)value; 32 DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime(); 33 ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime); 34 } 35 #endif 36 else 37 { 38 throw new Exception("Expected date object value."); 39 } 40 41 writer.WriteStartConstructor("Date"); 42 writer.WriteValue(ticks); 43 writer.WriteEndConstructor(); 44 } 45 46 /// <summary> 47 /// Reads the JSON representation of the object. 48 /// </summary> 49 /// <param name="reader">The <see cref="JsonReader"/> to read from.</param> 50 /// <param name="objectType">Type of the object.</param> 51 /// <param name="existingValue">The existing property value of the JSON that is being converted.</param> 52 /// <param name="serializer">The calling serializer.</param> 53 /// <returns>The object value.</returns> ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)54 public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 55 { 56 Type t = (ReflectionUtils.IsNullableType(objectType)) 57 ? Nullable.GetUnderlyingType(objectType) 58 : objectType; 59 60 if (reader.TokenType == JsonToken.Null) 61 { 62 if (!ReflectionUtils.IsNullableType(objectType)) 63 throw new Exception("Cannot convert null value to {0}.".FormatWith(CultureInfo.InvariantCulture, objectType)); 64 65 return null; 66 } 67 68 if (reader.TokenType != JsonToken.StartConstructor || !string.Equals(reader.Value.ToString(), "Date", StringComparison.Ordinal)) 69 throw new Exception("Unexpected token or value when parsing date. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value)); 70 71 reader.Read(); 72 73 if (reader.TokenType != JsonToken.Integer) 74 throw new Exception("Unexpected token parsing date. Expected Integer, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); 75 76 long ticks = (long)reader.Value; 77 78 DateTime d = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks); 79 80 reader.Read(); 81 82 if (reader.TokenType != JsonToken.EndConstructor) 83 throw new Exception("Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType)); 84 85 #if !PocketPC && !NET20 86 if (t == typeof(DateTimeOffset)) 87 return new DateTimeOffset(d); 88 #endif 89 90 return d; 91 } 92 } 93 }