Ruby JSON Serialization sucks for Time objects

This is something to be very careful of if you need to transfer data between two ruby-based systems using JSON. If you serialize a Time object it will serialize as a string, this means on deserialization it stays as a string

Let me demonstrate:

test_data = {“time” => Time.now}

json = test_data.to_json

# the timestamp looks like this in json “Tue Sep 28 14:37:37 -0400 2010”

results = JSON.parse(json)

results[“time”].is_a?(Time) #false!!! its still a string!

This can cause real problems if used in a real system when timestamps are critical to application logic.

Solutions

1. require ‘json/add/core’

if you use the json-ruby gem, it comes with a set of object extensions, these extensions serialize Time objects in a different way allowing them to be re-cast back to proper time objects during deserialization.

The negative to this is that you are producing very ruby-specific JSON, and you need to make sure you explicitly require these extensions whenever you want to serialize/deserialize which can be tricky.

Here is what a time object would look like using this:

”{"n":364019000,"json_class":"Time","s":1285689344}”

Not pretty.

2. Make time objects integers

This is the easiest and best solution for all involved. Just make them into unix timestamps by calling time.to_i. JSON deserializers in every language know how to parse integers, and unix timestamps are very easy to convert into a time object

Time.at(unix_timestamp)

Matthew Rathbone's Picture

Matthew Rathbone

CEO of Beekeeper Data. British. Data Nerd. Lucky husband and father. More about me

Join the discussion