2016-10-09 95 views
0

假設我有一個Event模型,其中date_time字段代表該活動舉行的日期時間,並且我希望查看所有保留的活動,比如'晚上10點之後',或者'早上7點之前'跨越多個日期。我怎麼能這樣做?獲取在一天中的特定時間之後創建的記錄


我首先想到的是這樣的:

scope :after_time ->(time){ where("events.date_time::time between ?::time and '23:59'::time", time) }

但是,這並不工作,因爲日期都存儲在UTC並轉換爲通過ActiveRecord的應用程序的時區。

假設我在阿德萊德當地時間下午5點以後正在尋找活動。最終的查詢是這樣的:

WHERE (events.date_time::time between '2016-10-09 06:30:00.000000'::time and '23:59'::time)

也就是說,因爲我的時區爲+10:30(阿德萊德時間),它現在試圖上午6:30和午夜,它真正需要找到之間計算在上午6:30至下午1:30之間創建的。現在

,在這個例子中,特別我大概可以砍東西一起制定必須考慮到時差的「午夜」時間是什麼。但是如果這段時間跨越午夜utc,則between <given time> and <midnight in Adelaide>計算不起作用。所以這個解決方案是失敗的。


UPDATE:

認爲我已經成功地得到我想要通過試錯的結果,但我不知道我的理解到底是什麼回事。

scope :after_time, ->(time) { time = time.strftime('%H:%M:%S') where_clause = <<-SQL (events.date_time at time zone 'UTC' at time zone 'ACDT')::time between ? and '23:59:59' SQL joins(:performances).where(where_clause, time) }

它基本上都轉成一個時區,每行的查詢最終看起來像WHERE '20:30:00' between '17:00:00' and '23:59:59',所以我不必擔心跨越午夜倍。

即使如此,我覺得有可能做到這一點適當的方式,所以我願意接受建議。

回答

0

檢查,如果這對你的作品,

s = DateTime.now.change(hour: 6, min: 30).utc 
e = Date.today.end_of_day.utc 
Event.where("date_time::time between ?::time and ?::time", s, e) 
+0

你誤解了問題。我需要在多個日期之間獲得事件,但是在這些日期的某些時間之後/之前。例如,數據庫中可能有3個事件,1月1日下午5點,1月2日下午6點,1月3日晚上7點一個。我希望能夠在晚些時候(或等於)下午6點找到所有的事件。也就是說,我需要一個查詢來查找第二個和第三個事件,但不是第一個。 – Obversity

+0

@Obversity我已經更新了我的答案。我認爲它會爲你工作。請對您的數據進行測試。 – dnsh

+0

下面是where子句生成的:WHERE(events.date_time :: time'2016-10-08 20:00:00.000000':: time和'2016-10-09 13:29:59.999999':: time之間的時間) '。你可能會猜到,這不會找到任何結果,因爲它將在'20:00:00'和'13:29:59'之間尋找記錄,這不是一個有效的時間段。 (我之前實際上已經嘗試過了,我可能應該在問題中提到這一點,對不起!) – Obversity

1

這可能會幫助你,然後你不需要DB的每一個日期轉換,而是可以將參數時間戳轉換成UTC時間:

scope :after, ->(start_time) { where('created_at::time > :time', time: start_time.utc.strftime('%H:%M:%S')) } 

現在, 例如我有3個事件以下時間戳(全部在UTC):

  1. 2013-04-11 11點43分43秒
  2. 2013-04-11 15時10分四十秒
  3. 2013-04- 12 7點39分26秒

,然後你可以撥打:

start_time = Time.zone.parse('2016-01-01 20:00:00') 
# => Fri, 01 Jan 2016 20:00:00 ACDT +10:30 
Event.after(start_time) # this will return 2 events(1, 2) 

查詢將是:

SELECT "events".* FROM "events" WHERE (created_at::time > '09:30:00') 

注:這將引發一個錯誤ActiveRecord::StatementInvalid: PG::AmbiguousColumn: ERROR: column reference "created_at" is ambiguous如果你會使用任何其他型號此查詢,將有created_at

相關問題