【问题标题】:How to automatically convert JSON time strings into Time objects with Ruby?如何使用 Ruby 将 JSON 时间字符串自动转换为 Time 对象?
【发布时间】:2018-04-02 18:24:30
【问题描述】:

当我使用 Ruby 使用以 JSON 格式返回时间字符串的 Web 服务 API 时,我希望它们自动转换为 Time 对象(或 DateTime 对象),这样我就不必自己手动进行.

例如,我希望它输出Time 而不是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

我了解时间不是 JSON 规范的一部分。我只是想知道是否有办法将 Ruby 的 stdlib JSON 解析器配置为自动解析日期,或者是否有一个库可以为您做到这一点。

【问题讨论】:

  • 您应该考虑选择唯一的答案,如果您认为它有帮助。

标签: ruby-on-rails json ruby time


【解决方案1】:

Active Support 可以在您设置 ActiveSupport.parse_json_times = true 时自动将 ISO 8601 格式的时间转换为 ActiveSupport::TimeWithZone 对象。

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

将输出:

{"now":"2018-04-02 13:19:40 -0500"}
{"now":"2018-04-02T13:19:40.291-05:00"}
String
ActiveSupport::TimeWithZone

请注意 Ruby stdlib 的默认时间如何无法被 Active Support 解析。只有 ISO 8601 格式的时间被成功转换。积极支持uses a regex to detect times。您可以read the tests 了解它支持的时间格式。看起来它支持 ISO 8601,但支持 Unix/POSIX/Epoch 时间戳。

当我创建 this issue against Rails 时,我在 Active Support 中得知了此功能。

一些历史:时间解析曾经是 Rails 中的默认行为,但后来为想要关闭它的人添加了ActiveSupport.parse_json_times,然后它被默认关闭,所以现在你必须选择它.

【讨论】:

  • 永远不要使用 Rails/ActiveSupport 的另一个原因。仅仅因为开发人员懒得手动转换日期时间而对输入中的所有内容应用正则表达式是疯狂、丑陋的,每个人都应该避免。
猜你喜欢
  • 2018-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-08
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多