我有几家商店,如果他们打开与否,我想展示。
问题是我现在有时间。
Time.current
=> Sat, 11 Jun 2016 11:57:41 CEST +02:00
然后如果我拿出商店的open_at
我得到:
2000-01-01 00:00:00 +0000
所以我现在拥有的是:
def current_business_hour(current_time: Time.current)
business_hours.where('week_day = ? AND open_at <= ? AND close_at >= ?',
current_time.wday, current_time, current_time).first
end
然后我检查是否存在current_business_hour。然而,这似乎是两个小时的计算错误。 open_at和close_at应该在Time.current
的时区内。
答案 0 :(得分:0)
在Rails中,日期和时间通常在数据库中保存为UTC ,Rails会在处理记录时自动将时间转换为本地时区。
但是,对于纯time
类型列,如果时间仅指定为字符串,则Rails不会执行此类自动转换。必须将指定为Time
对象,其中包括本地时区。
因此,例如,如果您希望将open_at
时间存储为14:00
本地时间,则不应使用普通字符串设置该属性,因为它将逐字保存到数据库中,未转换为UTC:
business_hour.open_at = '14:00'
business_hour.save
# => UPDATE `business_hours` SET `open_at` = '2000-01-01 14:00:00.000000', `updated_at` = '2016-06-11 15:32:14' WHERE `business_hours`.`id` = 1
business_hour.open_at
# => 2000-01-01 14:00:00 UTC
当Rails读回这样的记录时,它确实认为它是&#39; 00&#39; UTC,在CEST区域关闭2小时。
您应该将时间从字符串转换为Time
对象,因为它将包含正确的本地时区:
business_hour.open_at = Time.parse('14:00')
business_hour.save
# => UPDATE `business_hours` SET `open_at` = '2000-01-01 12:00:00.000000', `updated_at` = '2016-06-11 15:32:29' WHERE `business_hours`.`id` = 1
business_hour.open_at
# => 2016-06-11 14:00:00 +0200
请注意,该列现在以UTC时间存储。现在,您可以安全地将时间列与任何其他rails日期时间对象进行比较,例如Time.current
。