【问题标题】:ActiveRecord DateTime field not matching objectActiveRecord DateTime 字段与对象不匹配
【发布时间】:2012-02-02 17:53:22
【问题描述】:

我有一个 Course 模型,它有一个 datetime 属性。如果我从数据库中查看它,我会得到一次,如果我从对象中查看它,我会得到不同的日期和时间。

>> Course.last.attribute_for_inspect :datetime
=> "\"2012-01-04 01:00:00\""
>> Course.last.datetime
=> Tue, 03 Jan 2012 19:00:00 CST -06:00

有谁知道为什么这个值不同,我可以做些什么来解决它? Course.last.datetime 的时间是正确的,但由于混淆,我对课程表的查询无法正常工作。

【问题讨论】:

  • 您的数据库在没有偏移量的情况下以 UTC 存储内容。但是,Rails 应该在您查询时自动为您转换。您可以发布您用于其中一个损坏查询的代码吗?
  • application.rb 中的config.time_zone 的值是多少,如果它没有被评论?

标签: ruby-on-rails ruby activerecord time


【解决方案1】:

来自fine manual

attribute_for_inspect(attr_name)
为属性attr_name 的值返回类似#inspect 的字符串。
[...]
日期和时间属性以:db 格式返回。

因此,当attribute_for_inspect 用于日期时间时,它将返回数据库用于该值的字符串。 Rails 以 UTC 格式在数据库中存储时间,任何合理的数据库都将使用ISO 8601 来格式化进出时的时间戳。

2012-01-04 01:00:00 是 ISO 8601 格式的 UTC 时间戳。当 Rails 返回日期时间时,它会将其转换为 ActiveSupport::TimeWithZone 实例,并根据您在 application.rb 中配置的时区进行时区调整。您使用的是 CST 时区,比 UTC 晚了六个小时;从 01:00 减去 6 小时后,您将得到 19:00,并且您从午夜开始损失一天。人性化的格式 Tue, 03 Jan 2012 19:00:00 CST -06:00 正是 ActiveSupport::TimeWithZone 在 inspected 和控制台使用 x.inspect 来显示 x 时表示自己的方式。

就修复您的查询而言,只需在发送时间 t 之前使用 t.utc 即可。

【讨论】:

  • 我的主要问题是 ActiveRecord 在使用DATE() 函数时没有正确处理日期时间转换,感谢您的帮助
【解决方案2】:

在 application.rb 中配置 Rails 应用时区

将 config.active_record.default_timezone 设置为 :local,因为它在 application.rb 中默认设置为 :utc

将此代码粘贴到您的 application.rb 中

config.active_record.default_timezone = :local #or :utc
config.time_zone = "Singapore" #your timezone

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多