Comment puis-je trouver le nombre de jours entre deux objets Date dans Ruby?

141

Comment puis-je trouver le nombre de jours entre deux objets Date?

Brick
la source

Réponses:

170

Soustrayez la date de début de la date de fin:

endDate - beginDate 
Jedi agile
la source
2
pensez que vous voulez dire soustrayez la date de début de la date de fin :)
Nader
99
genre d'anticlimatique hein?
Brig
18
note: si vous utilisez Wirble dans irb (pour coloriser la sortie), le nombre rationnel aura un 1 concaténé à la fin. yikes! vous pouvez utiliser to_i pour convertir le résultat en entier
jwal
9
Si vous avez un DateTimeobjet, assurez-vous de le convertir en Datepremier, sinon il renvoie le nombre de secondes (je suppose).
Joshua Muheim
44
Notez également que la soustraction de deux Dateobjets vous donne un Rationalque vous devrez peut-être convertir en un entier, comme avec(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

Cela utilise un numéro de jour julien modifié .

De wikipedia :

La date julienne (JD) est l'intervalle de temps en jours et en fractions de jour depuis le 1er janvier 4713 avant JC Greenwich midi, calendrier prolptique julien.

RyanJM
la source
53

Cela peut avoir changé dans Ruby 2.0

Quand je fais cela, j'obtiens une fraction. Par exemple sur la console (soit irb, soit 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) 

Bien sûr, la conversion en un int donne le résultat attendu

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

Cela fonctionne également pour les objets DateTime, mais vous devez prendre en compte les secondes, comme cet exemple

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
la source
29

Dans Ruby 2.1.3, les choses ont changé:

> 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
la source
21

Que dis-tu de ça?

(beginDate...endDate).count

The Range est un ensemble de séries uniques. Et ...c'est un littéral de gamme exclusif.

C'est beginDate..(endDate - 1)pareil. Sauf que non.

Dans le cas où beginDate est égal à endDate , le premier élément sera exclu en raison d'unicité et ...exclura le dernier. Donc, si nous voulons des .countdates entre aujourd'hui et aujourd'hui, il renverra 0.

mpugach
la source
C'est une très bonne réponse, si le beginDate est plus ancien que le endDate, il reviendra 0, ce qui fonctionne parfaitement dans certains cas. De plus, si les deux dates sont identiques, il renverra 0. Il renvoie également un entier brut. D'autres réponses doivent être transformées en entiers ou vous devrez peut-être traduire à 0 si le résultat est négatif.
EmmanuelB
8

Cela a fonctionné pour moi:

(endDate - beginDate).to_i
Henok T
la source
6

Essaye ça:

num_days = later_date - earlier_date
Andrew Hare
la source
6

tout cela m'a conduit au résultat correct, mais j'ai fini par faire

DateTime.now.mjd - DateTime.parse("01-01-1995").mjd
Dabobert
la source
Une information à signaler: DateTime.parse dans Ruby s'attend à ce que la date soit donnée sous la forme JJ / MM / AAAA ou JJ-MM-AAAA. En tant qu'Américain, ça me dérange toujours!
rickumali
15
@rickumali En tant que membre du reste du monde, je remercie Ruby d'avoir utilisé "notre" format de date par défaut.
Claudio Holanda
7
@rickumali Ruby accepte également la date au YYYY-MM-DDformat, ce que tout le monde devrait utiliser de toute façon.
user513951
1

jours = (endDate - beginDate) / (60 * 60 * 24)

Michael
la source
5
La date est exprimée en jours, vous n'avez donc pas besoin de le faire. Je pense que votre solution devient pertinente avec les différences de DateTime.
suga_shane
1

Eh bien, faites attention à ce que vous entendez par «entre» aussi ...

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
la source