When I’m using Ruby to consume a web service API that returns time strings in JSON, I want them automatically converted into Time objects (or DateTime objects) so that I don’t have do it manually myself.
For example, I want this to output Time instead of String:
irb(main):001:0> require 'json'
=> true
irb(main):002:0> payload = JSON.generate({ now: Time.now })
=> "{\"now\":\"2018-04-02 13:15:56 -0500\"}"
irb(main):003:0> JSON.parse(payload)['now'].class
=> String
I understand that times are not part of the JSON spec. I’m just wondering if there’s a way to configure Ruby’s stdlib JSON parser to automatically parse dates, or if there’s a library that does this for you.
Active Support can automatically convert ISO 8601 formatted times into ActiveSupport::TimeWithZone objects when you set ActiveSupport.parse_json_times = true.
http://api.rubyonrails.org/classes/ActiveSupport/JSON.html
#!/usr/bin/env ruby
require 'active_support/json'
require 'active_support/time'
Time.zone = 'UTC'
ActiveSupport.parse_json_times = true
puts payload1 = JSON.generate({ now: Time.now })
puts payload2 = ActiveSupport::JSON.encode({ now: Time.now })
puts ActiveSupport::JSON.decode(payload1)['now'].class
puts ActiveSupport::JSON.decode(payload2)['now'].class
Which will output:
{"now":"2018-04-02 13:19:40 -0500"}
{"now":"2018-04-02T13:19:40.291-05:00"}
String
ActiveSupport::TimeWithZone
Notice how Ruby stdlib’s default time is not parseable by Active Support. Only the ISO 8601 formatted time gets successfully converted. Active Support uses a regex to detect times. You can read the tests to get a good idea of the time formats that it supports. Looks like it supports ISO 8601, but does not support Unix/POSIX/Epoch timestamps.
I was informed of this feature in Active Support when I created this issue against Rails.
Some history: Time parsing used to be the default behavior in Rails, but then ActiveSupport.parse_json_times was added for people who wanted to turn it off, and then it became turned off by default, so now you have to opt into it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With