James Ko James Ko - 5 months ago 28
JSON Question

Json.NET: Converting objects to DateTimeOffsets?

I'm making requests to an API service that returns dates as JSON in the following form:

{
"dateCreated": {
"date":8,
"day":4,
"hours":22,
"minutes":44,
"month":10,
"nanos":241000000,
"seconds":46,
"time":1194590686241,
"timezoneOffset":480,
"year":107
}
}


Here
time
is the number of milliseconds since the Unix epoch, so that's really the only property I want to pay attention to.

Would it be possible to write a custom Json.NET converter that deserializes this to something like

public class ApiResponse
{
public ApiResponse(DateTimeOffset dateCreated)
{
DateCreated = dateCreated;
}

public DateTimeOffset DateCreated { get; }
}


(The converter would call
DateTimeOffset.FromUnixTimeMilliseconds
on the object's
time
property.)

Here is the code I have so far:

public class ApiDateConverter : JsonConverter
{
public override bool CanWrite => false;

public override bool CanConvert(Type objectType)
{
return typeof(DateTimeOffset) == objectType;
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// What type is existingValue here? How do I get existingValue.time?
}

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

Answer

Option 1: Your ApiDateConverter can be completed by:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        dynamic jObject = JObject.Load(reader);

        return DateTimeOffset.FromUnixTimeMilliseconds(jObject.time.Value);
    }

Option 2: Without using custom converter:

public class DateSerialized
{
    public int date { get; set; }
    public int day { get; set; }
    public int hours { get; set; }
    public int minutes { get; set; }
    public int month { get; set; }
    public int nanos { get; set; }
    public int seconds { get; set; }
    public long time { get; set; }
    public int timezoneOffset { get; set; }
    public int year { get; set; }
}

public class ApiResponse
{
    [JsonIgnore]
    public DateTimeOffset DateCreated => DateTimeOffset.FromUnixTimeMilliseconds(DateSerialized.time);

    [JsonProperty("dateCreated")]
    private DateSerialized DateSerialized { get; set; }
}
Comments