我不知道如何,但我的控制台和我的服务器有两个不同的DateTime.now时区。如果我在控制台中运行DateTime.now,则返回以下内容:
Wed, 04 Dec 2013 14:27:23 -0500
但是,我的任务模型中有以下内容:
def self.already_expired
where("time_frame < ?", DateTime.now)
end
上面代码的目标是在'time_Frame'是过去日期的任务上触发一些任务方法。这是我称之为方法的地方:
task :change_it => :environment do
puts "yo yo you yo you"
@tasks = Task.already_expired
@tasks.each do |task|
puts "Kalabar" + task.inspect + "now time is:" + DateTime.now.to_s
end
end
服务器日志显示:
Task Load (1.2ms) SELECT "tasks".* FROM "tasks" WHERE (time_frame < '2013-12-04 17:25:37')
Kalabar#<Task id: 3, title: "task 1 - past", content: "Should show this one",
created_at: "2013-12-04 17:05:53", updated_at: "2013-12-04 17:05:53",
schedule_id: 2, amount: nil, time_frame: "2013-12-02 08:15:00">
now time is:2013-12-04T12:25:37-05:00
Kalabar#<Task id: 5, title: "another task - past",
content: "should show this one", created_at: "2013-12-04 17:11:23",
updated_at: "2013-12-04 17:11:23", schedule_id: 3, amount: nil,
time_frame: "2013-12-03 02:07:00">now time is:2013-12-04T12:25:37-05:00
Kalabar#<Task id: 6, title: "another task - future",
content: "should not show at first", created_at: "2013-12-04 17:11:23",
updated_at: "2013-12-04 17:25:09", schedule_id: 3, amount: nil,
time_frame: "2013-12-04 12:27:00">now time is:2013-12-04T12:25:37-05:00
因此,它将time_frame与'2013-12-04 12:25:37进行比较,即UTC。但是,当我打印DateTime.now.to_s时,它会打印'2012-12-04 08:15:00'。
我希望在进入数据库之前将所有内容转换为UTC。我也不明白为什么它有两个不同的DateTime.now时区这是我的问题
更新:
我将以下内容放在application.rb文件中:
config.time_zone = 'Eastern Time (US & Canada)'
现在,用户在东部时间输入日期时间,并将其存储为UTC时间。所以现在正在将time_frame正确地与DateTime.now进行比较。问题在于,如果我放入time_frame,它会把它放在东部时间。我不确定最新情况。它以UTC格式存储,但在东部时间打印。这是危险/正确吗?我在代码的任务块中添加了“put time_Frame”,如下所示:
task :change_it => :environment do
@tasks = Task.already_expired
@tasks.each do |task|
puts "Kalabar" + task.inspect + "now time is:" + DateTime.now.to_s
puts "time_frame is:" + task.time_frame.to_s
end
end
并输出:
Kalabar#<Task id: 3, title: "task 1 - past", content: "Should show this one", created_at: "2013-12-04 17:05:53", updated_at: "2013-12-04 17:05:53", schedule_id: 2, amount: nil, time_frame: "2013-12-02 08:15:00">now time is:2013-12-04T15:27:22-05:00
time_frame is:2013-12-02 03:15:00 -0500
Kalabar#<Task id: 7, title: "Task 1 - past by days", content: "Should always show", created_at: "2013-12-04 20:20:40", updated_at: "2013-12-04 20:20:40", schedule_id: 4, amount: nil, time_frame: "2013-12-02 09:02:00">now time is:2013-12-04T15:27:22-05:00
time_frame is:2013-12-02 04:02:00 -0500
Kalabar#<Task id: 8, title: "Task 2 - past by minutes", content: "should always show", created_at: "2013-12-04 20:20:40", updated_at: "2013-12-04 20:20:40", schedule_id: 4, amount: nil, time_frame: "2013-12-04 20:15:00">now time is:2013-12-04T15:27:22-05:00
time_frame is:2013-12-04 15:15:00 -0500
所以,正如你所看到的,在数据库中它是UTC,但当它把它放在东方时。它为什么这样做/它有危险吗?
答案 0 :(得分:2)
这是activerecord的默认行为,所有时间都将以UTC格式保存到数据库中。你不需要转换它。无论何时初始化当前时间,它都会返回一个时间对象,这意味着无论时区如何,它都将指向特定时间。无论你在不同的时区获得什么时间,如果你将其转换为UTC,都指向同一时间。所以,我不认为找到当前时间会有任何问题,因为任何时间都会在相应的时间内存储。
当您尝试使用字符串初始化时间对象(或通过传递DateTime属性)时,才会出现时区问题。时间对象使用系统时区进行解析,而不是使用application.rb中设置的时区。因此,在这种情况下,最好使用ActiveSupport时区对象解析时间。
答案 1 :(得分:0)
您可以在config/application.rb
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
答案 2 :(得分:0)
1)DateTime.now返回一个DateTime obj,你可以把它转换成你想要的任何时区(它仍然是它),如果你尝试用ActiveRecord做任何操作,ActiveRecord将首先将DateTime obj转换为UTC默认情况下,然后完成工作。
2)在将任何日期时间保存到数据库之前,请确保它是DateTime obj,如果您获得的日期时间是字符串,并且您知道时区,则可以使用DateTime.parse将其转换为DateTime obj:< / p>
irb(main):014:0> s = "2013-12-02 09:00:00 EST"
=> "2013-12-02 09:00:00 EST"
irb(main):015:0> sdt = DateTime.parse(s)
=> Mon, 02 Dec 2013 09:00:00 -0500
答案 3 :(得分:0)
我认为你不看两个时区。数据库中的所有时间(由task.inspect
显示)都是UTC。你是正确的,当你运行DateTime.now
时,你会得到一个代表你当前时区的时间的对象。很酷的事情是ActiveRecord非常聪明,可以将该对象更改为UTC以用于实际的sql命令。在控制台中试试这个:
Task.where("time_frame < ?", DateTime.now).to_sql
它应该将DateTime.now
转换为UTC表示,因此您应该获得您期望的结果。这有用吗?