Как Rails определяет завтрашнюю дату? - PullRequest
14 голосов
/ 02 марта 2012

В приложении на Rails 3.2 у меня есть определенный запрос для возврата всех элементов события с: due_date, равным сегодняшнему дню.

@due_today = Event.where(:due_date => Time.now.beginning_of_day..Time.now.end_of_day)

Я хочу изменить это, чтобы возвращать все события, причитающиеся сегодня и завтра.

Каков наилучший способ сделать это?

Я знаю, что мне доступны несколько вариантов:

Date.tomorrow
Date.current.tomorrow
Date.now.tomorrow
DateTime.now.tomorrow.to_date
Time.now.tomorrow.to_date
Date.current+1

Я уверен, что есть и другие.Все ли они взаимозаменяемы?Есть ли различия в производительности?Есть ли проблемы, связанные с разными подходами?Я бы приветствовал любые предложения о том, какой лучший способ сделать это.

Для дополнительной репутации: я также хочу отобразить: due_date как Today HH: MM или Tomorrow HH:ММ, где ЧЧ: ММ - время.Есть ли метод, добавленный в Rails, чтобы отображать даты как Сегодня или Завтра?Или мне нужно будет определить свою собственную область?

Большое спасибо!

Ответы [ 2 ]

29 голосов
/ 02 марта 2012

При сравнительном анализе я получаю:

N = 100000
Benchmark.bmbm do |test|
  test.report("Date.tomorrow") do
    N.times do
      x = Date.tomorrow
    end
  end
  test.report("Date.current.tomorrow") do
    N.times do
      x = Date.current.tomorrow
    end
  end
  # test.report("Date.now.tomorrow") # => Coughs up an exception, Date.now doesn't exist!
  test.report("DateTime.now.tomorrow.to_date") do
    N.times do 
      x = DateTime.now.tomorrow.to_date
    end    
  end
  test.report("Time.now.tomorrow.to_date") do
    N.times do
      x = Time.now.tomorrow.to_date
    end
  end
  test.report("Date.current+1") do
    N.times do
      x = Date.current+1
    end
  end
  test.report("DateTime.tomorrow") do
    N.times do 
      x = DateTime.now
    end    
  end
end

Результаты:

Rehearsal -----------------------------------------------------------------
Date.tomorrow                   1.640000   0.010000   1.650000 (  1.662668)
Date.current.tomorrow           1.580000   0.000000   1.580000 (  1.587714)
DateTime.now.tomorrow.to_date   0.360000   0.010000   0.370000 (  0.363281)
Time.now.tomorrow.to_date       4.270000   0.010000   4.280000 (  4.303273)
Date.current+1                  1.580000   0.010000   1.590000 (  1.590406)
DateTime.tomorrow               0.160000   0.000000   0.160000 (  0.164075)
-------------------------------------------------------- total: 9.630000sec

                                    user     system      total        real
Date.tomorrow                   1.590000   0.000000   1.590000 (  1.601091)
Date.current.tomorrow           1.610000   0.010000   1.620000 (  1.622415)
DateTime.now.tomorrow.to_date   0.310000   0.000000   0.310000 (  0.319628)
Time.now.tomorrow.to_date       4.120000   0.010000   4.130000 (  4.145556)
Date.current+1                  1.590000   0.000000   1.590000 (  1.596724)
DateTime.tomorrow               0.140000   0.000000   0.140000 (  0.137487)

Из вашего списка предложений, DateTime.now.tomorrow.to_date быстрее.

Обратите внимание на последнюю добавленную мною опцию: она возвращает объект Date и является самой быстрой из всех на милю страны. Это также один из самых читаемых человеком списков.

Если вы используете MYSQL, ваш запрос может быть быстрее, если вы используете функцию MySQL BETWEEN ():

@due_today = Event.where("due_date BETWEEN ? AND ?", DateTime.today, DateTime.tomorrow)

Хотя я не уверен, есть ли у вас индексы на events.due_date или BETWEEN все равно будет их использовать. Вам нужно будет сравнить оба теста, чтобы увидеть, что быстрее с большим набором данных.

Надеюсь, это поможет?

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

Как насчет этого?

1.day.from_now
2.days.from_now
3.days.from_now

Если вы хотите увеличить определенное время

1.day.from_now(start_time) # gives a day after the start time 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...