Parsing JSON DateTime from Newtonsoft's JSON Serializer
I've serialized an object using Newtonsoft's JSON serializer, and the DateTime has come through as:
/Date(1237588418563+0000)/
When I $.evalJSON() on that, it is an object but I can't find any normal Date methods like toUTCString on it.
Any ideas what I can do with this?
Solution 1:
Use one of the JsonConverters that come with Json.NET for working with dates to get a better format. JavaScriptDateTimeConverter will automatically give you a JavaScript date.
public class LogEntry
{
public string Details { get; set; }
public DateTime LogDate { get; set; }
}
[Test]
public void WriteJsonDates()
{
LogEntry entry = new LogEntry
{
LogDate = new DateTime(2009, 2, 15, 0, 0, 0, DateTimeKind.Utc),
Details = "Application started."
};
string defaultJson = JsonConvert.SerializeObject(entry);
// {"Details":"Application started.","LogDate":"\/Date(1234656000000)\/"}
string javascriptJson = JsonConvert.SerializeObject(entry, new JavaScriptDateTimeConverter());
// {"Details":"Application started.","LogDate":new Date(1234656000000)}
string isoJson = JsonConvert.SerializeObject(entry, new IsoDateTimeConverter());
// {"Details":"Application started.","LogDate":"2009-02-15T00:00:00Z"}
}
Documentation: Serializing Dates in JSON with Json.NET
Solution 2:
I came up with a different approach which might be useful to some. Basically I create my own CustomDateConverter that I call when I need it. The converter takes 2 parameters, a date format e.g. yyyy-MM-dd HH:mm:ss
and a TimeZoneInfo, which allows me to convert the date from UTC to the user's time zone:
public class JSONCustomDateConverter : DateTimeConverterBase
{
private TimeZoneInfo _timeZoneInfo;
private string _dateFormat;
public JSONCustomDateConverter(string dateFormat, TimeZoneInfo timeZoneInfo)
{
_dateFormat = dateFormat;
_timeZoneInfo = timeZoneInfo;
}
public override bool CanConvert(Type objectType)
{
return objectType == typeof(DateTime);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(TimeZoneInfo.ConvertTimeFromUtc(Convert.ToDateTime(value), _timeZoneInfo).ToString(_dateFormat));
writer.Flush();
}
You can use it like this:
var jsonString = JsonConvert.SerializeObject(myObject, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Converters = new List<JsonConverter>() { new JSONCustomDateConverter("yyyy-MM-dd HH:mm:ss", loggedUser.Timezone) } });
Obviously you could remove anything related to time zone if you only want custom date formatting. Let me know it that helped!
Solution 3:
As of Newtonsoft Json.Net version 4.5r5 you use the JsonPropertyAttribute Class class and set its ItemConverterType Property property. Usage:
// class to be serialized
public class MyClass
{
[JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))]
public DateTime? DateTime1;
public DateTime? DateTime2;
}
As I have observed this will set the DateTimeConverter for all properties in this class not just the one before which is declared.
Solution 4:
Ran into the same problem, and found a solution based on the link from Adam:
new Date(yourDate.substr(yourDate.indexOf("(") + 1, 13) - 0));
It looks like a Unix timestamp, which javascript is easily able to convert into a date object. The - 0
is simply to make javascript treat the substr
output as an integer... I guess you could Number()
it as well, if you don't like the looks of - 0
Solution 5:
The JSON object contained something like this:
var data = {"CreatedDate":"/Date(1327572000000-1000)/"});
///
var oddDateTimeZone = data.CreatedDate;
var utcDateTime = oddDateTimeZone.substr(oddDateTimeZone.indexOf("(")+1, 13);
var utcZone = oddDateTimeZone.substr(oddDateTimeZone.indexOf("-")+1, 4);
var utcDateTimeZone = new Date(Number(utcDateTime)-(Number(utcZone)));
but, still it would be better to fix the JSON object so the date function fired without using something like eval() or window[]. Maybe in jQuery. Not sure.
Don't forget that the offset could be +
and not just -
for the offset!