【问题标题】:Setting a DateTime to UTC rather than having it write the current system time将 DateTime 设置为 UTC,而不是让它写入当前系统时间
【发布时间】:2014-06-03 15:33:00
【问题描述】:

我有一个这样的类方法:

  def self.seed
    InventoryPeriod.delete_all
    (1..8).each do |i|
      self.create! name: "name#{i}", start_datetime: DateTime.new(2014,i,1), end_datetime:DateTime.new(2014,i,-1), location_id: 12
    end
  end

但它似乎应该以 UTC 写入数据库(DateTime.new(2014,i,1).utc 不这样做)但它没有并且基本上关闭了 8 小时。

例如:

| 51 | 2014-08-01 00:00:00 | 2014-08-31 00:00:00

但应该是:

| 51 | 2014-07-31 16:00:00 | 2014-08-30 16:00:00

对此最好的解决方案是什么?希望一些我不知道的东西 - 似乎应该有,因为它一定很常见。还是按必要的时间手动调整?

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    问题在于,当您执行 DateTime.new(y,m,d) 时,时区默认为 UTC。因此,在您的示例中,它将DateTime 存储在 UTC 中,与您的预期相比仅相差 8 小时。

    这样做

    DateTime.new(2014,8,1,0,0,0, '+8')
    DateTime.new(2014,8,-1,0,0,0, '+8')
    DateTime.new(2014,8,1,0,0,0, '+8').getutc
    DateTime.new(2014,8,-1,0,0,0, '+8').getutc
    

    会给出这个结果

    2014-08-01T00:00:00+08:00
    2014-08-31T00:00:00+08:00
    2014-07-31T16:00:00+00:00
    2014-08-30T16:00:00+00:00
    

    在这里它被插入到您的代码中。

    (1..8).each do |i|
      self.create! name: "name#{i}", start_datetime: DateTime.new(2014,i,1,0,0,0, '+8').getutc, end_datetime: DateTime.new(2014,i,-1,0,0,0, '+8').getutc, location_id: 12
    end
    

    【讨论】:

      【解决方案2】:

      如果您的属性是时区感知的,并且您希望跳过某些属性的时区转换,那么您可以执行以下操作:

      Model_Name.skip_time_zone_conversion_for_attributes = [:attribute_name]
      

      或者一般你可以在模型内部调用这个:

      skip_time_zone_conversion_for_attributes
      

      参考:http://api.rubyonrails.org/v3.0.0/classes/ActiveRecord/Timestamp.html

      为此,请确保您没有在application.rb 文件中指定任何特定时区。

      或者,如果您想要一个固定的时区而不是 UTC:

      请参考How to change default timezone for Active Record in Rails?

      希望对你有帮助:)

      【讨论】:

      • 如果真的对你有帮助,请采纳以备日后参考。
      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 2013-04-29
      • 2016-12-04
      • 2017-12-07
      • 2015-03-17
      • 2015-04-28
      • 2018-10-04
      相关资源
      最近更新 更多