2012-03-02 21 views
11

En una aplicación de Rails 3.2, tengo una consulta definida para devolver todos los elementos del evento con: due_date igual a today.¿Cuál es la manera de Rails de definir la fecha de mañana?

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

Quiero modificar esto para devolver todos los eventos para hoy y mañana.

¿Cuál es la mejor manera de hacerlo?

Sé que hay varias opciones disponibles para mí:

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

Estoy seguro de que hay otros. ¿Todos estos son intercambiables? ¿Hay alguna diferencia en el rendimiento? ¿Hay algún problema asociado con diferentes enfoques? Me gustaría recibir cualquier sugerencia acerca de cuál es la mejor forma de hacerlo .

Para felicitaciones adicionales: También quiero mostrar el: due_date como Hoy HH: MM o Mañana HH: MM, donde HH: MM es el momento. ¿Hay algún método incorporado en Rails para mostrar fechas como Hoy o Mañana? ¿O tendré que definir mi propio alcance?

¡Muchas gracias!

+0

yo no me preocuparía demasiado el rendimiento. Probablemente no estará calculando la fecha miles de veces en un ciclo cerrado, por lo que las diferencias de rendimiento son insignificantes. Ve con el que es más legible. Tenga en cuenta que 'current' toma timezone en cuenta mientras' now' no. – Dennis

Respuesta

21

Evaluación comparativa de estos, me sale:

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 

Resultados:

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) 

de la lista de sugerencias, DateTime.now.tomorrow.to_date es más rápido.

Echa un vistazo a la última opción que agregué, devuelve un objeto Date y es la más rápida del grupo por una milla de país. También es uno de los más legibles por humanos de la lista.

asumiendo que usted está utilizando MySQL, la consulta podría ser más rápido si utiliza MySQL que hay entre la función():

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

Aunque no estoy seguro de si tiene índices en events.due_date o si entre la voluntad todavía use estos. Deberá comparar ambos para ver cuál es más rápido con un gran conjunto de datos.

Espero que ayude?

+0

¡Gracias, excelente respuesta! Sin embargo, DateTime hoy devuelve 'NoMethodError: método privado 'today' llamado para DateTime: Class'. ¿Alguna idea de por qué esto sería? Además, estoy usando Postgres en lugar de MYSQL, pero creo que el operador 'BETWEEN' es aún válido. –

+0

Lo siento, mi culpa. Intenté llamar a 'DateTime.today' en lugar de' DateTime.now'. Y el operador 'BETWEEN' está trabajando. ¡Gracias! ¿Sabes cómo puedo mostrar la fecha de hoy como "Hoy" en Rails? –

+0

Parece que desea mostrar las fechas en formatos personalizados según la situación. Echa un vistazo a esta publicación en el blog: http://gavinmorrice.com/blog/posts/tagged/strftime y esta esencia https://gist.github.com/1957685 – bodacious

11

¿Qué tal esto?

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

Si desea incrementar un tiempo específico

1.day.from_now(start_time) # gives a day after the start time 
Cuestiones relacionadas