{ "title":"Mozilla Firefox", "id":24, "parent":2, "dateAdded":1356753810000000, "lastModified":1356753810000000, "type":"text/x-moz-place-container", "children":[] }
class Bookmark { public string title; public string id; [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))] public DateTime dateAdded; [JsonProperty(ItemConverterType = typeof(JavaScriptDateTimeConverter))] public DateTime lastModified; public string type; public string root; public long parent; public List<Bookmark> children; } private static void Main(string[] args) { var json = File.ReadAllText(@"T:/bookmarks-2013-11-13.json"); var bookmarks = JsonConvert.DeserializeObject<Bookmark>(json); }
I get an exception when I try running this,
Additional information: Error reading date. Unexpected token: Integer. Path 'dateAdded'
I thought by using the JavaScriptDateTimeConverter
, JSON.NET could figure out how to deserialize those unix timestamps (ms μs since epoch). What's the easiest way to do this?
Having trouble finding documentation on the converters... it probably wouldn't be too hard to write one myself if necessary.
Edit: Those are actually microseconds, not milliseconds.
A common way to deserialize JSON is to first create a class with properties and fields that represent one or more of the JSON properties. Then, to deserialize from a string or a file, call the JsonSerializer. Deserialize method.
Overloads. Deserialize(Stream, Type, JsonSerializerOptions) Reads the UTF-8 encoded text representing a single JSON value into a returnType . The Stream will be read to completion.
Unix time is a way of representing a timestamp by representing the time as the number of seconds since January 1st, 1970 at 00:00:00 UTC. One of the primary benefits of using Unix time is that it can be represented as an integer making it easier to parse and use across different systems.
Let’s convert this timestamp to a datetime object… This example converts a Unix timestamp to a datetime object in Python. For this task, we can apply the fromtimestamp () function as shown below: my_datetime = datetime. fromtimestamp( my_timestamp) print( my_datetime) # 2018-08-18 05:01:29
The best solution would be that during the the unmarshal of the JSON, we can convert the timestamps directly into a time.Time instance. There is (as usual) a neat way of handling this in Go. The trick is to define a custom type and implement MarshalJSON and UnmarshalJSON.
The DateTime module in Python is used to deal with date and time-related issues in Python. The fromtimestamp () method is one of the functions included in this module. The date class’s function fromtimestamp () computes and returns the date corresponding to a specified timestamp.
The utc.now function returns the current time in the UTC timezone. In the time module, the timegm function returns a Unix timestamp. The timetuple () function of the datetime class returns the datetime’s properties as a named tuple. To obtain the Unix timestamp, use print (UTC).
I cleaned up Cris's solution a tad and implemented WriteJson
:
class Bookmark { public string title; public long id; [JsonConverter(typeof(MicrosecondEpochConverter))] public DateTime dateAdded; [JsonConverter(typeof(MicrosecondEpochConverter))] public DateTime lastModified; public string type; public string root; public long parent; public List<Bookmark> children; public string uri; public override string ToString() { return string.Format("{0} - {1}", title, uri); } } public class MicrosecondEpochConverter : DateTimeConverterBase { private static readonly DateTime _epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteRawValue(((DateTime)value - _epoch).TotalMilliseconds + "000"); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.Value == null) { return null; } return _epoch.AddMilliseconds((long)reader.Value / 1000d); } } internal class Program { private static void Main(string[] args) { var jsonString = File.ReadAllText(@"T:/bookmarks-2013-11-13.json"); var rootMark = JsonConvert.DeserializeObject<Bookmark>(jsonString); var ret = JsonConvert.SerializeObject(rootMark); } }
There's a built-in way to convert from unix timestamp to DateTime without having to write your own class:
[JsonConverter(typeof(UnixDateTimeConverter))] public DateTime lastModified;
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Converters_UnixDateTimeConverter.htm
The annotation in Cris' answer is not correct, as JavaScriptDateTimeConverter
is for Date(52231943)
format rather than the Unix timestamp from the OP.
I realize this question is a few years old now so it's highly likely this class has been added since this question has been asked, but this may help anyone who comes across the same issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With