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?

Brigg
quelle

Antworten:

170

Subtrahieren Sie das Anfangsdatum vom Enddatum:

endDate - beginDate 
Agile Jedi
quelle
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.

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

mpugach
quelle
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
Henok T.
quelle
6

Versuche dies:

num_days = later_date - earlier_date
Andrew Hare
quelle
6

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

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

Michael
quelle
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
estani
quelle