2017-09-16 7 views
0

私はデフォルトのデータベースとしてPostgresqlを備えたレールアプリケーションを持っています。私は2つのdatetimeの列start_dateとend_dateを持つテーブルPromotionPipeLineを持っています。 時刻は、データベース列にUTC形式で保存されます。私は現在のタイムゾーンの時間を保存された列time.Butと比較したいが、それはいくつかの問題があるようだ。 postgresql utcをローカル時間に変換していないのですか?

scope :changing_promotion, -> {where("(to_char(start_date At Time zone 'UTC', 'YYYY-MM-DD HH24')='#{(Time.now).strftime('%Y-%m-%d %H')}') or (to_char(end_date At Time zone 'UTC', 'YYYY-MM-DD HH24')='#{(Time.now).strftime('%Y-%m-%d %H')}')")} 

の下に与えられたとして、私はスコープを定義していると私は私の

SELECT "promotion_pipe_lines".* FROM "promotion_pipe_lines" WHERE ((to_char(start_date At Time zone 'UTC', 'YYYY-MM-DD HH24')='2017-09-16 15') or (to_char(end_date At Time zone 'UTC', 'YYYY-MM-DD HH24')='2017-09-16 15')) 

それとしてSQLクエリを示す

PromotionPipeLine.changing_promotion 

Railsのコンソールとしてレールコンソールでそれを呼び出しています何も返しません。 上記のSQLクエリをpgAdminで実行すると、予想されるレコードが得られます。

+0

'Time.now'はしばしば' Time.now.utc'と同じではありません、システムのタイムゾーンで時間を与えます。 – max

答えて

0

あなたはレールからそれを渡すことによってPostgres own date/time機能の代わりを使用して、現在の時刻を取得することができます:

SELECT "promotion_pipe_lines".* 
FROM "promotion_pipe_lines" 
WHERE 
    date_trunc('hour', start_date AT TIME ZONE 'UTC') = date_trunc('hour', current_time AT TIME ZONE 'UTC') 
OR 
date_trunc('hour', end_date AT TIME ZONE 'UTC')) = date_trunc('hour', current_time AT TIME ZONE 'UTC') 

date_trunc('hour', ...は、1時間の精度に切り捨てられます。

あなたはどうなるのActiveRecordのスコープにこれを適応するには:

class PromotionPipeLine 

    # `scope` is just syntactic sugar to create class methods 
    # use a regular class method if the defintion does not fit a lambda 
    def self.changing_promotion 
    where(
     SQL <<~ 
     date_trunc('hour', start_date AT TIME ZONE 'UTC') = date_trunc('hour', current_time AT TIME ZONE 'UTC') 
     OR 
     date_trunc('hour', end_date AT TIME ZONE 'UTC')) = date_trunc('hour', current_time AT TIME ZONE 'UTC') 
     SQL 
    ) 
    end 
end 
+0

'current_time AT TIME ZONE 'UTC'は、postgresが他のいくつかのタイムゾーンに設定されている場合にのみ必要です。 – max

関連する問題