How to deserialize a unix timestamp (μs) to a DateTime from JSON?

Solution 1:

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);
    }
}

Solution 2:

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.

Solution 3:

You can create a custom DateTime converter

  var bookmarks = JsonConvert.DeserializeObject<Bookmark>(json,
                                                      new MyDateTimeConverter());

public class MyDateTimeConverter : Newtonsoft.Json.JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var t = long.Parse((string)reader.Value);
        return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(t);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

another approach is to double annotate the class member,

[JsonProperty(PropertyName="dateAdded")] 
[JsonConverter(typeof(JavaScriptDateTimeConverter))]
public DateTime dateAdded;