2012-03-07 26 views
20

¿Cómo puedo determinar el número de días entre dos instancias de Tiempo en Ruby?Número de días entre dos instancias de Tiempo

> earlyTime = Time.at(123) 
> laterTime = Time.now 
> time_difference = laterTime - earlyTime 

me gustaría para determinar el número de días en time_difference (no estoy preocupado por fracciones de días. El redondeo hacia arriba o hacia abajo está bien).

+2

¿Le preocupa el horario de verano? – Phrogz

+1

buena pregunta. El cálculo del tiempo de ahorro de energía y los años bisiestos no es crítico, ya que este cálculo solo genera un recordatorio por correo electrónico para algunas personas. – SundayMonday

Respuesta

34

La diferencia de dos veces es en segundos. Divídalo por número de segundos en 24 horas.

(t1 - t2).to_i/(24 * 60 * 60) 
+3

Esto no funciona durante los cambios de horario de verano. – ChrisInEdmonton

+0

¿Cuál es una buena manera de hacerlo, entonces eso explica el horario de verano? – Tallboy

+0

@Tallboy lo que hago es almacenar todo en 'UTC' y hacer estos cálculos con instancias' Time' de 'zone'' UTC'. El horario de verano se mostrará de forma adecuada cuando se renderice cualquier "Tiempo" en una vista. –

5
earlyTime = Time.at(123) 
laterTime = Time.now 
time_difference = laterTime - earlyTime 
time_difference_in_days = time_difference/1.day # just divide by 1.day 
+0

Lo siento, ha mencionado a Ruby pero no específicamente Ruby on Rails. No creo que obtenga la funcionalidad de 1.day en vanilla ruby. –

+1

eso es correcto, no es así. A menos que necesite la parte adecuada de active_support. –

+0

Esto no funciona durante los cambios de horario de verano. – ChrisInEdmonton

15
require 'date' 
days_between = (Date.parse(laterTime.to_s) - Date.parse(earlyTime.to_s)).round 

Editar ... o, más sencillamente ...

require 'date' 
(laterTime.to_date - earlyTime.to_date).round 
+0

Los tiempos de Stringifying solo para analizarlos de inmediato me parecen un poco raros :) –

+0

@Sergio Tienes razón, eso fue tonto.Editado :) – Phrogz

4

Para tener en cuenta el horario de verano (horario de verano), que tendría que contarlo por los días. Tenga en cuenta que esto supone menos de un día se cuenta como 1 (redondeado):

num = 0 
cur = start_time 
while cur < end_time 
    num += 1 
    cur = cur.advance(:days => 1) 
end 
return num 
+0

demasiado lento para uso general –

3
[1] pry(main)> earlyTime = Time.at(123) 
=> 1970-01-01 01:02:03 +0100 
[2] pry(main)> laterTime = Time.now 
=> 2014-04-15 11:13:40 +0200 
[3] pry(main)> (laterTime.to_date - earlyTime.to_date).to_i 
=> 16175 
0

Ninguna de estas respuestas realmente funcionará si no se desea estimar y desea tener en cuenta la luz del día tiempo de ahorro Por ejemplo, a las 10 a.m. del miércoles anterior al cambio de hora de otoño y a las 10 a.m. del miércoles siguiente, el tiempo entre ellas sería de 1 semana y 1 hora. Durante la primavera sería 1 semana menos 1 hora. Con el fin de obtener el tiempo exacto puede utilizar el siguiente código

def self.days_between_two_dates later_time, early_time 
    days_between = (later_time.to_date-early_time.to_date).to_f 
    later_time_time_of_day_in_seconds = later_time.hour*3600+later_time.min*60+later_time.sec 
    earlier_time_time_of_day_in_seconds = early_time.hour*3600+early_time.min*60+early_time.sec 
    days_between + (later_time_time_of_day_in_seconds - early_time_time_of_day_in_seconds)/1.0.day 
end 
2

Aquí es una respuesta simple que funciona en el horario de verano:

numDays = ((laterTime - earlyTime)/(24.0*60*60)).round

60 * 60 es el número de segundos en una hora 24.0 es el número de horas en un día. Es un flotador porque algunos días son un poco más de 24 horas, algunos son menos. Entonces cuando dividimos por el número de segundos en un día todavía tenemos un flotador, y la ronda redondeará al número entero más cercano.

Así que si cruzamos DST, de cualquier forma, seguiremos redondeando al día más cercano. Incluso si estás en una zona horaria extraña que cambia más de una hora para DST.

Cuestiones relacionadas