2013-10-21 95 views
2

在我的應用程序中,用戶爲任務設置特定的結束時間。當任務被加載時,它將使用(在這種情況下,自我是任務)該任務的信息對應的簽入:在Rails的不同區域中比較DateTime/Time的問題

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

這不是一個好的/永久的解決方案。我現在正處於一段時間緊張狀態,這將滿足我的需求。

回答

3

我建議您將config.time_zone保留爲UTC,這樣您就不會在數據庫中看到這些奇怪的變化。

如果要強制應用的用戶特定的時區,那麼你最好的選擇是爲before_filterApplicationController

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

這樣的話,所有的時間將被保存到數據庫作爲UTC時間,但會在東部時間顯示在網站上。


這樣做的原因很簡單:它更容易從一個通用的中部時間(UTC)比它是從某任意點回UTC,然後再轉換到其他任意點轉換。