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"

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.


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

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"

@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

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

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.


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

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

-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

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.