关于ruby:比较Rails中不同区域的DateTime / Time的问题

Issue comparing DateTime/Time in different zones in Rails

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

1
2
3
4
5
6
7
8
  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设置为"Eastern Time(US& Canada"),但不是将其创建为UTC,而是将其作为EST提交,然后从那里减去4小时。

1
2
3
4
5
6
7
[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:

1
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))

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


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

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

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

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

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