Что такое метод Rails для определения даты завтрашнего дня?

В приложении Rails 3.2 у меня есть запрос, который возвращает все элементы Event с: 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: MM, где HH: MM - это время. Есть ли метод, который использовался в Rails для отображения дат как сегодня или завтра? Или мне нужно определить мою собственную область?

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

Ответ 1

Сравнивая их, я получаю:

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 все равно будет их использовать. Вам нужно будет сравнить оба, чтобы узнать, что быстрее с большим набором DATA.

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

Ответ 2

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

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