Рельсы где () и часовые пояса - PullRequest
1 голос
/ 09 марта 2012

Я пытаюсь найти «записи», созданные сегодня (в моем текущем часовом поясе), используя следующее:

Entry.where("DATE(created_at) = DATE(?) AND email = ?", Time.now, email)

Time.now дает мне время в текущей зоне, но запрос выглядит такэто поиск по времени UTC каждой колонки созданной записи.

Есть идеи, как найти записи, созданные сегодня в часовом поясе сервера?

Ответы [ 4 ]

13 голосов
/ 09 марта 2012

Вы теряете информацию о часовом поясе, как только вы вызываете функцию DATE() в вашем SQL.Необходимо помнить о двух вещах:

  1. Все в базе данных будет в формате UTC, а все включает результат DATE().
  2. Одиндата (то есть день) в вашем местном часовом поясе может легко пересекать две даты в UTC, поэтому вам нужно смотреть на всю метку времени (на с обеих сторон ), а не только на компоненты даты (UTC).

Примерно так должно работать:

now = Time.now
Entry.where('created_at between :start and :end and email = :email',
    :start => now.beginning_of_day,
    :end   => now.end_of_day,
    :email => email
)

Время должно быть автоматически конвертировано в UTC.Возможно, вы захотите обработать верхнюю границу немного по-другому;использование end_of_day дает вам 23:59:59, поэтому есть немного места для того, чтобы что-то проскользнуло в то, что вы хотите захватить.Вы можете обойти эту проблему, используя явный полуоткрытый интервал (а не закрытый интервал, который использует SQL between), например:

now = Time.now
Entry.where('created_at >= :start and created_at < :end and email = :email',
    :start => now.beginning_of_day,
    :end   => now.tomorrow.beginning_of_day,
    :email => email
)
1 голос
/ 09 марта 2012

Используйте Time.zone.now. При этом будет использоваться объект ActiveSupport::TimeWithZone, который будет автоматически преобразован в UTC при использовании в поиске в базе данных.

0 голосов
/ 04 июня 2017

Сначала вы должны получить часовой пояс, а затем смещение часового пояса. Например current_time_zone это

America / Los_Angeles

Найти смещение часового пояса:

 Time.now.in_time_zone(current_time_zone).utc_offset / 3600) * -1

7

В контроллере:

 start_date_format = DateTime.strptime(@start_date, date_format)
 start_date_format_with_hour = 
 DateTime.strptime((start_date_format.to_i + timezone_offset*60*60).to_s,'%s').strftime(date_format)

 end_date_format = DateTime.strptime(@end_date, date_format)
 end_date_format_with_hour = DateTime.strptime((end_date_format.to_i + timezone_offset*60*60).to_s,'%s').strftime(date_format)

 @filters_date = "invoices.created_at >= ? AND invoices.created_at < ?", start_date_format_with_hour, end_date_format_with_hour
0 голосов
/ 09 марта 2012

Использование Time.now.utc?

...