Wie kann ich die Anzahl der Tage zwischen zwei Datumsobjekten in Ruby ermitteln?


141

Wie kann ich die Anzahl der Tage zwischen zwei Datumsobjekten ermitteln?

Antworten:


170

Subtrahieren Sie das Anfangsdatum vom Enddatum:

endDate - beginDate 

2
denke du meinst subtrahiere das Startdatum vom Enddatum :)
Nader

99
Art von antiklimaktischen wie?
Brig

18
Hinweis: Wenn Sie Wirble in irb verwenden (um die Ausgabe einzufärben), wird die rationale Zahl mit einer 1 bis zum Ende verkettet. Huch! Vielleicht möchten Sie to_i verwenden, um das Ergebnis in eine Ganzzahl
umzuwandeln

9
Wenn Sie ein DateTimeObjekt haben, müssen Sie es Datezuerst konvertieren , andernfalls wird die Anzahl der Sekunden zurückgegeben (ich denke).
Joshua Muheim

44
Beachten DateSie auch, Rationaldass Sie durch Subtrahieren von zwei Objekten möglicherweise eine Ganzzahl (endDate - beginDate).to_i
eingeben müssen

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

Dies verwendet eine modifizierte julianische Tagesnummer .

Aus Wikipedia :

Das julianische Datum (JD) ist das Zeitintervall in Tagen und Bruchteilen eines Tages seit dem 1. Januar 4713 v. Chr. Greenwich-Mittag, julianischer proleptischer Kalender.


53

Dies hat sich möglicherweise in Ruby 2.0 geändert

Wenn ich das mache, bekomme ich einen Bruchteil. Zum Beispiel auf der Konsole (entweder irb oder Schienen 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) 

Natürlich ergibt das Casting auf ein int das erwartete Ergebnis

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

Dies funktioniert auch für DateTime-Objekte, Sie müssen jedoch Sekunden berücksichtigen, wie in diesem Beispiel

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

In Ruby 2.1.3 haben sich folgende Dinge geändert:

> 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

Wie wäre es damit?

(beginDate...endDate).count

Die Reihe besteht aus einer Reihe einzigartiger Serien. Und ...ist ein exklusives Range-Literal.

So beginDate..(endDate - 1)ist es auch. Außer ist nicht.

Wenn beginDate gleich endDate ist , wird das erste Element aufgrund der Eindeutigkeit ausgeschlossen und ...das letzte ausgeschlossen. Wenn wir also .countzwischen heute und heute datieren möchten, wird 0 zurückgegeben.


Dies ist eine sehr gute Antwort. Wenn das beginDate älter als das endDate ist, wird es zurückgegeben 0, was in einigen Fällen perfekt funktioniert. Wenn die beiden Daten identisch sind, wird 0 zurückgegeben. Außerdem wird eine einfache Ganzzahl zurückgegeben. Andere Antworten müssen in ganze Zahlen umgewandelt werden, oder Sie müssen möglicherweise in 0 übersetzen, wenn das Ergebnis negativ ist.
EmmanuelB

8

Das hat bei mir funktioniert:

(endDate - beginDate).to_i


6

All dies führte mich zum richtigen Ergebnis, aber ich endete damit

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

Ein Leckerbissen: DateTime.parse in Ruby erwartet, dass das Datum als TT / MM / JJJJ oder TT-MM-JJJJ angegeben wird. Als Amerikaner wirft es mich immer ab!
Rickumali

15
@rickumali Als Mitglied aus dem Rest der Welt danke ich Ruby für die Verwendung von "unserem" Standard-Datumsformat.
Claudio Holanda

7
@rickumali Ruby akzeptiert das Datum auch im YYYY-MM-DDFormat, was sowieso jeder verwenden sollte.
user513951

1

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


5
Das Datum wird in Tagen angegeben, Sie müssen dies also nicht tun. Ich denke, Ihre Lösung wird mit DateTime-Unterschieden relevant.
suga_shane

1

Nun, pass auf, was du auch mit "zwischen" meinst ...

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.