Cuenta el número de días entre dos fechas

149

¿Cómo cuento el número de días entre estas dos fechas?

start_date = Date.parse "2012-03-02 14:46:21 +0100"
end_date =  Date.parse "2012-04-02 14:46:21 +0200"
andkjaer
fuente

Respuestas:

207

Con las clases Date (y DateTime) puede hacer (end_date - start_date).to_ipara obtener el número de días de diferencia.

Andrew Francia
fuente
55
@ MichaelDurrant Estás haciendo una suposición injustificada. El usuario no especifica si son cadenas o no. De hecho, dado que están usando Rails, lo más probable es que las fechas provengan de ActiveRecord, que las convertirá automáticamente en objetos de fecha. El texto dado es idéntico a la representación del objeto Date también, por lo que es muy probable que provenga de una fuente nativa.
Andrew France
84
Eso me da la diferencia en segundos NO en días con rieles v3 / 4
2called-chaos
66
Por lo que puedo decir, el comportamiento sigue siendo el mismo en todas las versiones recientes de Ruby y ActiveSupport, que incluyen 2.0 y 4.1.0 respectivamente. TimeSin embargo, los objetos devuelven segundos.
Andrew France
55
para ampliar la respuesta @ 2called-chaos, para obtener los días que necesitaría (end_date - start_date) /1.day, lo que le daría un flotante. Si desea tener días completos solo puede usar ((end_date - start_date) /1.day) .ceil
David K.
2
@David Excepto que el comentario de @ 2called-chaos se refiere erróneamente a Timeobjetos, no a Dateobjetos. ¿Quizás podría actualizar los nombres en su comentario para reflejar que no son fechas?
Andrew France
109

Asumiendo eso end_datey start_dateambos son de clase ActiveSupport::TimeWithZoneen Rails, puede usar:

(end_date.to_date - start_date.to_date).to_i
sotavento
fuente
2
Si tiene que ver con campos de tabla, esta respuesta es el camino a seguir; en lugar del más valorado aquí.
Ben
No funciona (Time.zone.now.to_date - 23.hours.ago.to_date).to_i, da 1 y debería ser 0
Yuri Ghensev
3
@YuriGhensev, depende de cuándo ejecute su código de ejemplo, por ejemplo, ahora Time.zone.now.to_datedevuelve "Mié, 15 de noviembre de 2017", mientras que 23.hours.ago.to_datedevuelve "Mar, 14 de noviembre de 2017". La diferencia en el número de días es y debe ser 1 a menos que haya ejecutado su código en la hora anterior a la medianoche.
Lee
35

Rails tiene algunos ayudantes integrados que pueden resolver esto por usted. Una cosa a tener en cuenta es que esto es parte de los Actionview Helpers, por lo que no estarán disponibles directamente desde la consola.

Prueba esto

<% start_time =  "2012-03-02 14:46:21 +0100" %>
<% end_time   =  "2012-04-02 14:46:21 +0200" %>
<%= distance_of_time_in_words(start_time, end_time)  %>

 "about 1 month"
Justin Herrick
fuente
@MaayanNaveh no debería ser cuando necesita el número real para los cálculos.
Fedcomp
Esta pregunta es uno de esos casos en los que la pregunta en sí es mejor formulada de manera diferente. Si sigue las otras respuestas aquí, se encontrará con casos en los que a veces desea que se muestren semanas o años en lugar de días. Esto realmente debería ser aceptado como la respuesta "correcta" de Rails.
Dylan Pierce
34

Seguí obteniendo resultados en segundos, así que esto funcionó para mí:

(Time.now - self.created_at) / 86400
thatdankent
fuente
1
@Epigene 1.dayno es rubycomo OP solicitado (en las etiquetas). Es Rails, o más específico active support, aunque created_ates básicamente un Modelmétodo en el Railsmodo ..
Roko
26

para obtener el número de días en un rango de tiempo (solo un recuento de todos los días)

(start_date..end_date).count
(start_date..end_date).to_a.size
#=> 32

para obtener el número de días entre 2 fechas

(start_date...end_date).count
(start_date...end_date).to_a.size
#=> 31
a14m
fuente
Gracias por esto @ a14m! Me dio una manera de hacer capturas de fechas inclusivas y exclusivas :)
Kris Boyd
18

Ninguna de las respuestas anteriores (a esta fecha) da la diferencia correcta en días entre dos fechas.

El que más se acerca es aquel quequent . Una respuesta completa convertiría to_iy luego dividiría:

(Time.now.to_i - 23.hours.ago.to_i) / 86400
>> 0

(Time.now.to_i - 25.hours.ago.to_i) / 86400
>> 1

(Time.now.to_i - 1.day.ago.to_i) / 86400
>> 1

En el ejemplo específico de la pregunta, no se debe analizar Datesi el tiempo transcurrido es relevante. Usar en su Time.parselugar.

Yuri Ghensev
fuente
Esto puede no funcionar como se esperaba cuando los tiempos cruzan una transición de horario de verano en adelante. En este caso, la duración del día de transición del horario de verano es legítimamente inferior a 24 horas, pero debido a la aritmética de enteros ese día no se reflejará en absoluto.
PinnyM
4

Para tener el número de días completos entre dos fechas ( DateTimeobjetos):

((end_at - start_at).to_f / 1.day).floor
dorio
fuente
El mismo problema de horario de verano que la respuesta que dio Yuri. La aritmética con el tiempo nunca es tan sencilla como cabría esperar :)
PinnyM
0

Para obtener el número de días de diferencia por dos fechas:

(start.to_date...end.to_date).count - 1
or 
(end.to_date - start.to_date).to_i
giapnh
fuente
-8
def business_days_between(date1, date2)
  business_days = 0
  date = date2
  while date > date1
   business_days = business_days + 1 unless date.saturday? or date.sunday?
   date = date - 1.day
  end
  business_days
end
Teja
fuente
3
mucho más fácil restar los objetos de fecha.
OpenCoderX
El OP nunca preguntó sobre ajustes por días hábiles. Esto es realmente complicado de todos modos.
Nathan