gpt4 book ai didi

ruby - DateTime 序列化和反序列化

转载 作者:数据小太阳 更新时间:2023-10-29 08:16:33 24 4
gpt4 key购买 nike

我想将 Ruby DateTime 对象序列化为 json。不幸的是,我的方法不是对称的:

require 'date'
date = DateTime.now
DateTime.parse(date.to_s) == date
=> false

我可以使用一些任意的 strftime/parse 字符串组合,但我相信一定有更好的方法。

最佳答案

不幸的是,接受的答案不是一个好的解决方案。一如既往,marshal/unmarshal 是您应该只作为最后手段使用的工具,但在这种情况下,它可能会破坏您的应用程序。

OP 特别提到将日期序列化为 JSON。每RFC 7159 :

JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32. The default encoding is UTF-8, and JSON texts that are encoded in UTF-8 are interoperable in the sense that they will be read successfully by the maximum number of implementations; there are many implementations that cannot successfully read texts in other encodings (such as UTF-16 and UTF-32).

现在让我们看看我们从 Marshal 那里得到了什么:

marsh = Marshal.dump(DateTime.now)
# => "\x04\bU:\rDateTime[\vi\x00i\x03\xE0\x7F%i\x02s\xC9i\x04\xF8z\xF1\"i\xFE\xB0\xB9f\f2299161"
puts marsh.encoding
# -> #<Encoding:ASCII-8BIT>

marsh.encode(Encoding::UTF_8)
# -> Encoding::UndefinedConversionError: "\xE0" from ASCII-8BIT to UTF-8

除了返回一个人类不可读的值之外,Marshal.dump 还为我们提供了一个无法转换为 UTF-8 的值。这意味着将它放入(有效的)JSON 的唯一方法是以某种方式对其进行编码,例如base-64。

没有必要这样做。已经有一种非常可互操作的方式来表示日期和时间:ISO 8601 .我不会讨论为什么它是 JSON 的最佳选择(一般而言),但这里的答案很好地涵盖了它:What is the "right" JSON date format? .

从 Ruby 1.9.3 开始,DateTime 类就有了 iso8601 classinstance分别解析和格式化 ISO 8601 日期的方法。后者采用一个参数来指定小数秒的精度(例如 3 表示毫秒):

require "date"

date = DateTime.now
str = date.iso8601(9)
puts str
# -> 2016-06-28T09:35:58.311527000-05:00

DateTime.iso8601(str) == date
# => true

请注意,如果您指定较小的精度,这可能不起作用,因为例如58.311 不等于 58.3115279(纳秒)的精度对我来说似乎是安全的,因为 DateTime 文档说:

The fractional number’s precision is assumed at most nanosecond.

但是,如果您要与可能使用更高精度的系统进行互操作,则应考虑到这一点。

最后,如果你想让 Ruby 的 JSON 库自动使用 iso8601 进行序列化,重写 as_jsonto_json 方法:

unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
require 'json'
end
require 'date'

class DateTime
def as_json(*)
iso8601(9)
end

def to_json(*args)
as_json.to_json(*args)
end
end

puts DateTime.now.to_json
# -> "2016-06-28T09:35:58.311527000-05:00"

关于ruby - DateTime 序列化和反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13594289/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com