¿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?

Bergantín
fuente

Respuestas:

170

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

endDate - beginDate 
Jedi ágil
fuente
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.

RyanJM
fuente
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 
Joe Basirico
fuente
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 
wieczorek1990
fuente
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.

mpugach
fuente
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
8

Esto funcionó para mí:

(endDate - beginDate).to_i
Henok T
fuente
6

Prueba esto:

num_days = later_date - earlier_date
Andrew Hare
fuente
6

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

DateTime.now.mjd - DateTime.parse("01-01-1995").mjd
dabobert
fuente
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)

Miguel
fuente
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
estani
fuente