¿Cómo puedo encontrar el número de días entre dos objetos Date en Ruby?


141

¿Cómo puedo encontrar el número de días entre dos objetos Date?

Respuestas:


170

Reste la fecha de inicio de la fecha de finalización:

endDate - beginDate 

2
cree que quiere decir restar la fecha de inicio de la fecha de finalización :)
Nader

99
tipo de anticlimático eh?
Brig

18
nota: si está utilizando Wirble en irb (para colorear la salida), el número racional tendrá un 1 concatenado al final. ¡Ay! es posible que desee usar to_i para convertir el resultado a un número entero
jwal

9
Si tiene un DateTimeobjeto, asegúrese de convertirlo Dateprimero, de lo contrario, devolverá una cantidad de segundos (supongo).
Joshua Muheim

44
También tenga en cuenta que restar dos Dateobjetos le da un Rationalque puede que necesite escribir en un número entero, como con(endDate - beginDate).to_i
MusikAnimal

98
irb(main):005:0> a = Date.parse("12/1/2010")
=> #<Date: 4911063/2,0,2299161>

irb(main):007:0> b = Date.parse("12/21/2010")
=> #<Date: 4911103/2,0,2299161>

irb(main):016:0> c = b.mjd - a.mjd
=> 20

Esto utiliza un número de Julian Day modificado .

De wikipedia :

La fecha juliana (JD) es el intervalo de tiempo en días y fracciones de un día desde el 1 de enero de 4713 a. C. a mediodía de Greenwich, calendario proleptico juliano.


53

Esto puede haber cambiado en Ruby 2.0

Cuando hago esto me sale una fracción. Por ejemplo en la consola (ya sea irb o rails c)

2.0.0-p195 :005 > require 'date'
 => true 
2.0.0-p195 :006 >  a_date = Date.parse("25/12/2013")
 => #<Date: 2013-12-25 ((2456652j,0s,0n),+0s,2299161j)> 
2.0.0-p195 :007 >  b_date = Date.parse("10/12/2013")
 => #<Date: 2013-12-10 ((2456637j,0s,0n),+0s,2299161j)> 
2.0.0-p195 :008 > a_date-b_date
 => (15/1) 

Por supuesto, enviar a un int da el resultado esperado

2.0.0-p195 :009 > (a_date-b_date).to_i
 => 15 

Esto también funciona para objetos DateTime, pero debe tener en cuenta segundos, como este ejemplo

2.0.0-p195 :017 >   a_date_time = DateTime.now
 => #<DateTime: 2013-12-31T12:23:03-08:00 ((2456658j,73383s,725757000n),-28800s,2299161j)> 
2.0.0-p195 :018 > b_date_time = DateTime.now-20
 => #<DateTime: 2013-12-11T12:23:06-08:00 ((2456638j,73386s,69998000n),-28800s,2299161j)> 
2.0.0-p195 :019 > a_date_time - b_date_time
 => (1727997655759/86400000000) 
2.0.0-p195 :020 > (a_date_time - b_date_time).to_i
 => 19 
2.0.0-p195 :021 > c_date_time = a_date_time-20
 => #<DateTime: 2013-12-11T12:23:03-08:00 ((2456638j,73383s,725757000n),-28800s,2299161j)> 
2.0.0-p195 :022 > a_date_time - c_date_time
 => (20/1) 
2.0.0-p195 :023 > (a_date_time - c_date_time).to_i
 => 20 

29

En Ruby 2.1.3 las cosas han cambiado:

> endDate = Date.new(2014, 1, 2)
 => #<Date: 2014-01-02 ((2456660j,0s,0n),+0s,2299161j)> 
> beginDate = Date.new(2014, 1, 1)
 => #<Date: 2014-01-01 ((2456659j,0s,0n),+0s,2299161j)> 
> days = endDate - beginDate
 => (1/1) 
> days.class
 => Rational 
> days.to_i
 => 1 

21

¿Qué tal esto?

(beginDate...endDate).count

La gama es un conjunto de series únicas. Y ...es un exclusivo rango literal.

Así beginDate..(endDate - 1)es igual. Excepto que no lo es.

En caso de que beginDate sea igual a endDate , el primer elemento será excluido debido a la unicidad y ...excluirá al último. Entonces, si queremos .countfechas entre hoy y hoy, devolverá 0.


Esta es una muy buena respuesta, si el beginDate es anterior al endDate, regresará 0, lo que funciona perfectamente en algunos casos. Además, si las dos fechas son iguales, devolverá 0. También devuelve un entero simple. Otras respuestas deben transformarse en enteros o puede que tenga que traducir a 0 si el resultado es negativo.
EmmanuelB



6

todo esto me condujo al resultado correcto, pero terminé haciendo

DateTime.now.mjd - DateTime.parse("01-01-1995").mjd

Un dato para señalar: DateTime.parse en Ruby espera que la fecha se dé como DD / MM / AAAA o DD-MM-AAAA. Como estadounidense, ¡siempre me desanima!
rickumali

15
@rickumali Como miembro del resto del mundo, agradezco a Ruby por usar "nuestro" formato de fecha predeterminado.
Claudio Holanda

77
@rickumali Ruby también acepta la fecha en YYYY-MM-DDformato, que es lo que todos deberían usar de todos modos.
user513951

1

días = (endDate - beginDate) / (60 * 60 * 24)


55
La fecha es en términos de días, por lo que no necesita hacer esto. Creo que su solución se vuelve relevante con las diferencias de fecha y hora.
suga_shane

1

Bueno, cuídate de lo que quieres decir con "entre" también ...

days_apart = (to - from).to_i     # from + days_apart = to
total_days = (to - from).to_i + 1 # number of "selected" days
in_between_days = (to - from).to_i - 1 # how many days are in between from and to, i.e. excluding those two days
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.