ruby-on-rails
  • ruby
  • postgresql
  • timezone
  • activesupport
  • 2013-12-22 45 views 2 likes 
    2

    我有一些新聞事件通過postgresql日期時間列存儲在數據庫中。但是,我想針對事件發生的時間進行查詢。類似於從Rails日期時間列(帶時區)查詢一天中的時間

    Event.where("occurred_at < '11:00'") 
    

    如果這是一個postgresql時間列,您可以執行此操作。

    要添加一個額外的皺紋,我有我的Rails的時區設置爲東部時間爲整個應用程序

    config.time_zone = 'Eastern Time (US & Canada)' 
    

    所以,如果你嘗試以某種方式提取數據庫的時候,那個時候將是UTC ,所以在半年時間內,時間比較將會減少1小時(因爲夏令時)。

    我唯一能想到的就是維護一個單獨的'時間'類型的數據庫列。

    編輯和澄清

    這個問題的棘手的部分是,UTC,因爲夏令時的半年期間偏移變化。 Time.zone.parse(「2013-01-01 10:00」)給出2013年1月1日10:00 EST-05:00(即15:00 UTC),而六個月後Time.zone.parse(「2013- 07-01 10:00「)給出了2013年7月1日上午10:00至04:00(即14:00 UTC)。所以你不能只在不知道日期的情況下查詢時間。

    +0

    請參閱:http://stackoverflow.com/questions/4002958/rails-utc-to-local-and-daylight-savings-time演示如何Rails將帳戶時區偏移使用夏時制區域。 – Beartech

    +0

    您是否想要查詢時間,而不管它發生的那一天? – Beartech

    +0

    是的,確切地說。無論如何 – idrinkpabst

    回答

    3

    我已經完全刪除並重寫了這個答案,因爲舊的答案只適用於SQL,而不是OP詢問的Postgres。

    我能找到的唯一簡單方法就是使用寶石。寶石是「tod」,可以在這裏找到:https://github.com/JackC/tod

    首先,您需要將gem 'tod'添加到您的Gemfile並運行包。然後,您將在時間的DB中創建一個列。

    添加到您的Event.rb模型

    class Event < ActiveRecord::Base 
        serialize :time, Tod::TimeOfDay 
    

    現在你有辦法抓住一個時間戳,並只保存時間(即13時45分00秒)的序列化格式。 TimeOfDay課程將爲您提供調用和操作該領域所需的方法。

    在你create動作,你可以有這樣的事情(假定稱爲「tod_stamp」型時間,並呼籲DateTime對象的數據庫列:occured_at):

    def create 
        @event = Event.new(event_params) 
        tod_stamp = @event.occured_at.strftime('%H:%M:%S') 
        @event.tod_stamp = TimeOfDay.parse(tod_stamp) 
    
        respond_to do |format| 
        if @event.save 
         format.html { redirect_to @event, notice: 'Event was successfully created.' } 
         format.json { render action: 'show', status: :created, location: @event } 
        else 
         format.html { render action: 'new' } 
         format.json { render json: @event.errors, status: :unprocessable_entity } 
        end 
        end 
    end 
    

    現在,當你問在DB這樣的事情:

    my_events = Event.where( 「?tod_stamp <」, 「10:00:00」)

    喲你會根據事件記錄的實際時間得出結果。如果您在使用夏令時的時區,則無關緊要。您還可以獲得TimeOfDay解析,比較和處理的其他方法,作爲tod主頁上的文檔。

    像往常一樣,我應該尋找一個寶石,然後再嘗試重新發明輪子。 :-) 希望這可以幫助。

    +0

    好的答案。是的,時區部分是它的棘手部分。 Time.zone.parse(「2013-01-01 10:00」)給出2013年1月1日10:00 EST -05:00,而六個月後Time.zone.parse(「2013-07-01 10:00」 )給出了2013年7月1日10:00至04:00。所以通過將時間(而不是日期)轉換爲UTC,我將在半年內發生1小時的錯誤。 – idrinkpabst

    +0

    我認爲你仍然困惑Rails在問一段時間時返回的內容與UTC中的數據庫內容有什麼區別。無論一年中的什麼時候,美國東部時間08:00總是會翻譯到UTC的03:00。假設您在一月份,並保存了即將發生的08:00:00的時間戳,Rails將在數據庫列中保存UTC的日期時間爲03:00。 6月份,當您在08:00節省另一個時間戳時,Rails仍然會將其轉換爲03:00。它正在進行-04:00和-05:00的更改,因爲您(或您的計算機)已經實際改變了您的時鐘前後或小時。 – Beartech

    +0

    良好的評論,但(1)UTC時間*確實*隨夏時制改變。 1月1日的美國東部時間是UTC 15:00,但7月1日的美國東部時間10:00是UTC。在Rails中,你可以使用Time.zone.parse(「2013-01-01 10:00」)。utc來驗證。 (2)你爲什麼在你的例子中查詢'created_at'?我相信,如果你查詢'happen_at',你會得到不同的答案。 – idrinkpabst

    相關問題