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?

Réponses:


170

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

endDate - beginDate 

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.


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 

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 

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.


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


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

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)


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.