Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to convert dates from Google Reader and Facebook API with Json.NET

DZone's Guide to

How to convert dates from Google Reader and Facebook API with Json.NET

· ·
Free Resource

Lately I’m working together with Daniela on a news feed reader for WP7 and one of its features is Google Reader synchronization. (It is called FeedTso, and if you are interested in knowing when it will be released I recommend you go and subscribe to the newsletter on the FeedTso site.)

I’ll talk about the Google Reader API in a future post (I’ll opensource the API when FeedTso is on the MarketPlace) but for the moment I want to discuss how I deserialize the JSON Date that I receive from the Google Reader API (and from what I’ve been told, Facebook API behaves the same) using Json.NET.

Json.NET has two converters to DateTime:

But unfortunately the Google Reader and Facebook APIs, instead of returning the date in one of the two aforementioned formats, they just return the number representing the unix time: 1290774032435185.

The easy solution would have been to just deserialize to an integer and then expose another property that converted the unix time timestamp to a DateTime, but I wanted something cleaner, so I decided to create a UnixDateTimeConverter for Json.NET.

I looked at the code of the original JavaScriptDateTimeConverter and I basically created mine removing all the parts that were parsing the “new Data(“ part of the value.

public class UnixDateTimeConverter: DateTimeConverterBase
{
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
Type t = ReflectionUtils.IsNullableType(objectType)
? Nullable.GetUnderlyingType(objectType) : objectType;
if (reader.TokenType == JsonToken.Null)
{
if (!ReflectionUtils.IsNullableType(objectType))
{
throw new Exception(String.Format("Cannot convert null value to {0}.",
CultureInfo.InvariantCulture, new object[] { objectType }));
}
return null;
}
if (reader.TokenType != JsonToken.Integer)
{
throw new Exception(String.Format("Unexpected token parsing date. Expected Integer, got {0}.",
CultureInfo.InvariantCulture, new object[] { reader.TokenType }));
}
long ticks = (long)reader.Value;
DateTime d = ticks.ConvertFromUnixTimestamp();
if (t == typeof(DateTimeOffset))
{
return new DateTimeOffset(d);
}
return d;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
long ticks = 0;
if (value is DateTime)
{
ticks = ((DateTime)value).ToUniversalTime().ConvertToUnixTimestamp();
}
else
{
if (!(value is DateTimeOffset))
{
throw new Exception("Expected date object value.");
}
DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
ticks = dateTimeOffset.ToUniversalTime().UtcDateTime.ConvertToUnixTimestamp();
}
writer.WriteValue(ticks);
}
}

I also had to implement a few utility functions because the original converter uses some private methods: a small helper to check whether a type is Nullable and an updated version of my UnixTime to DateTime conversion methods (now implemented as extension methods):

static class DateTimeUtils
{
public static DateTime ConvertFromUnixTimestamp(this long timestamp)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp);
}

public static long ConvertToUnixTimestamp(this DateTime date)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
TimeSpan diff = date - origin;
return (long)Math.Floor(diff.TotalSeconds);
}
}

This the first time I extended Json.NET and I’ve to say I’m impressed: the parsing is extremely well thought, no wonder why Json.NET is faster than the official DataContractJsonSerializer serializer.

In case you needed something similar, I packaged the 3 classes in zip file to make it easier to download.

Download
Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}