Ruby JSON Serialization sucks for Time objects
Hire me to supercharge your Hadoop and Spark projects
I help businesses improve their return on investment from big data projects. I do everything from software architecture to staff training. Learn More
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)