0

有具有属性when和的任务模型duration

create_table "tasks", force: true do |t|
  ...
  t.datetime "when"
  t.integer  "duration"
  ...
end

我编写了检查任务是否处于活动状态的方法,以便我可以在页面上显示它。这是主动方法:

  def active?
    if (self.when + self.duration) > Time.now
      true
    end
  end

我尝试在控制台中检查对象:

t.when + t.duration
=> Sun, 08 Sep 2013 01:01:00 UTC +00:00
DateTime.now
=> Sun, 08 Sep 2013 01:57:13 +0200
t.active?
=> true

true我输入了 1:00 时间和 1 分钟duration,我希望这不是真的。

似乎when数据库中的列没有保存在正确的时区,所以它给出了不正确的结果。如何解决这个问题?

4

2 回答 2

1

似乎当数据库中的列未保存在正确的时区时

1) Rails 在将时间插入数据库之前会自动将时间转换为 UTC 时间(这是一件好事),这意味着时间的偏移量为 "+0000" 。这意味着如果您将晚上 8 点的时间保存到数据库中,并且您的服务器位于偏移量为“+0600”的时区,那么等效的 UTC 时间是下午 2 点,因此下午 2 点会保存在数据库中。换句话说,您本地服务器的时间比 UTC 时间早 6 小时,这意味着当您服务器所在时区的晚上 8 点时,UTC 时区的下午 2 点。

2)当您比较日期时,ruby 会考虑时区偏移量——换句话说,ruby 会将所有时间转换为同一时区,然后比较时间。这是一个例子:

2.0.0p247 :086 > x = DateTime.strptime('28-01-2013 08:00:00 PM +6', '%d-%m-%Y %I:%M:%S %p %z')
 => Mon, 28 Jan 2013 20:00:00 +0600 
2.0.0p247 :087 > y = DateTime.strptime('28-01-2013 08:20:00 PM +7', '%d-%m-%Y %I:%M:%S %p %z')
 => Mon, 28 Jan 2013 20:20:00 +0700 
2.0.0p247 :088 > x < y
 => false 

如果只是比较两个 Datetime 对象的时间,x 小于 y。但是,y 在偏移量为 +7 的时区中的时间为晚上 8:20,这相当于在偏移量为 +6 的时区中的时间晚上 7:20。因此,y 实际上小于 x。您需要将苹果与苹果进行比较,这意味着您需要在心理上比较已转换为同一时区的时间,以获得与 ruby​​/rails 产生的相同结果。

3)您可以使用 rails utc() 方法将 Time.now 转换为 UTC 时间:

2.0.0p247 :089 > x = Time.now
 => 2013-09-07 8:00:00 +0600 
2.0.0p247 :090 > x.utc
 => 2013-09-07 02:00:00 UTC 

这就是 ruby​​ 在比较 Time.now 之前所做的task.when + task.duration

4)您可能会发现使用您想要使用的时间创建 DateTime 对象更方便:

DateTime.strptime('28-01-2013 08:00:00 PM +0', '%d-%m-%Y %I:%M:%S %p %z'

因为您可以将偏移量指定为零,所以您不必创建预期转换为 UTC 时间的时间。

或者你可以使用 change() 方法,它会导致 offset() 改变而不转换时间:

2.0.0p247 :011 > x = DateTime.now
 => Sun, 08 Sep 2013 00:34:08 +0600 
2.0.0p247 :012 > x.change offset: "+0000"
 => Sun, 08 Sep 2013 00:34:08 +0000 
于 2013-09-08T00:59:06.860 回答
0

ActiveRecord 默认以 UTC 存储时间戳。请参阅如何更改 Rails 中 Active Record 的默认时区?用于更改默认时区。

您也可以只使用 Time#in_time_zone 将 t.when 转换为您的时区,请参阅http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html

于 2013-09-08T00:45:05.153 回答