在Rails中比较不同区域中的DateTime / Time的问题

时间:2013-10-21 03:39:36

标签: ruby-on-rails ruby datetime

在我的应用程序中,用户为任务设置特定的结束时间。加载任务时,它会使用该任务的信息创建相应的CheckIn(在这种情况下,self是任务):

  def create_checkin_end_time(day)
    week = (Date.today .. Date.today + 6)
      week.each do |day_of_week|
        if day_of_week.strftime("%A") == day
          return DateTime.new(day_of_week.year, day_of_week.month, day_of_week.day, self.end_time.hour, self.end_time.min)
        end
      end
  end

我已将config.time_zone设置为“东部时间(美国和加拿大”),但不是将其创建为UTC,而是将其作为EST提交,然后从那里减去4小时。

[2] pry(main)> CheckIn.last.end_time
  CheckIn Load (0.7ms)  SELECT "check_ins".* FROM "check_ins" ORDER BY "check_ins"."id" DESC LIMIT 1
=> Sun, 20 Oct 2013 19:30:00 EDT -04:00

[3] pry(main)> Task.last.end_time
  Task Load (0.7ms)  SELECT "tasks".* FROM "tasks" ORDER BY "tasks"."id" DESC LIMIT 1
=> Sun, 20 Oct 2013 23:30:00 EDT -04:00

该模型实例的结束时间应该是晚上11点,具体取决于用于创建它的任务。这是我第一次在Rails中处理时间,所以任何帮助都会非常感激。谢谢。

更新 将其切换回UTC并将方法添加到ApplicationController,但这里真正的问题是我创建CheckIn的方式。因为Task.end_time在创建中用作引用,并且作为EST从数据库中调用,所以在创建CheckIn时偏移量加倍。真奇怪。我的解决方案是使用.change创建:

CheckIn.create(task_id: self.id, start_time: self.create_checkin_start_time(day).change(:hour => self.start_time.hour + 4), end_time: self.create_checkin_end_time(day).change(:hour => self.end_time.hour + 4))

这不是一个伟大/永久的解决方案。我现在处于时间紧迫状态,这符合我的需求。

1 个答案:

答案 0 :(得分:3)

我建议将config.time_zone保留为UTC,这样您就不会在数据库中看到这种奇怪的变化。

如果您想对应用程序的用户强制使用特定时区,那么您最好的选择是在before_filterApplicationController

before_filter :set_timezone
def set_timezone
  Time.zone = "Eastern Time (US & Canada)"
end

那样,所有时间都会以UTC时间的形式保存到数据库中,但会在东部时间显示在网站上。


这样做的原因非常简单:从一个通用中心时间(UTC)转换比从一些任意点转换回UTC然后转换到其他任意点更容易。