Bagaimana saya bisa menemukan jumlah hari antara dua objek Date di Ruby?

141

Bagaimana saya bisa menemukan jumlah hari antara dua objek Date?

Penjara
sumber

Jawaban:

170

Kurangi tanggal mulai dari tanggal akhir:

endDate - beginDate 
Agile Jedi
sumber
2
pikir maksudmu kurangi tanggal mulai dari tanggal akhir :)
Nader
99
semacam antiklimaks ya?
Brig
18
Catatan: jika Anda menggunakan Wirble di irb (untuk mewarnai output) bilangan rasional akan memiliki 1 disatukan sampai akhir. Astaga! Anda mungkin ingin menggunakan to_i untuk mengonversi hasilnya menjadi integer
jwal
9
Jika Anda memiliki DateTimeobjek, pastikan untuk mengonversi menjadi yang Datepertama, jika tidak, ia mengembalikan jumlah detik (saya kira).
Joshua Muheim
44
juga perhatikan mengurangi dua Dateobjek memberi Anda Rationalbahwa Anda mungkin perlu mengetikkan ke integer, seperti(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

Ini menggunakan Nomor Hari Julian yang Dimodifikasi .

Dari wikipedia :

Tanggal Julian (JD) adalah interval waktu dalam beberapa hari dan sebagian kecil dari hari sejak 1 Januari 4713 SM Greenwich siang, kalender proleptik Julian.

RyanJM
sumber
53

Ini mungkin telah berubah di Ruby 2.0

Ketika saya melakukan ini saya mendapatkan sebagian kecil. Misalnya pada konsol (baik irb atau 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) 

Tentu saja, casting ke int memberikan hasil yang diharapkan

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

Ini juga berfungsi untuk objek DateTime, tetapi Anda harus mempertimbangkan detik, seperti contoh ini

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
sumber
29

Di Ruby 2.1.3 hal telah berubah:

> 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
sumber
21

Bagaimana dengan ini?

(beginDate...endDate).count

Range adalah serangkaian serial unik. Dan ...merupakan Range literal eksklusif.

Begitu beginDate..(endDate - 1)juga. Kecuali tidak.

Dalam hal ketika beginDate sama dengan endDate , elemen pertama akan dikecualikan karena keunikan dan ...akan mengecualikan yang terakhir. Jadi, jika kita ingin .counttanggal antara hari ini dan hari ini, itu akan mengembalikan 0.

mpugach
sumber
Ini adalah jawaban yang sangat bagus, jika tanggal mulai lebih tua dari tanggal akhir, itu akan kembali 0, yang berfungsi dengan baik pada beberapa kasus. Juga, jika dua tanggal adalah sama, itu akan mengembalikan 0. Ini juga mengembalikan bilangan bulat biasa. Jawaban lain harus diubah menjadi bilangan bulat atau Anda mungkin harus menerjemahkan ke 0 jika hasilnya negatif.
EmmanuelB
8

Ini bekerja untuk saya:

(endDate - beginDate).to_i
Henok T
sumber
6

Coba ini:

num_days = later_date - earlier_date
Andrew Hare
sumber
6

semua ini mengarahkan saya ke hasil yang benar, tetapi akhirnya saya melakukannya

DateTime.now.mjd - DateTime.parse("01-01-1995").mjd
dabobert
sumber
Satu berita gembira untuk menunjukkan: DateTime.parse di Ruby mengharapkan tanggal akan diberikan sebagai DD / MM / YYYY, atau DD-MM-YYYY. Sebagai orang Amerika, itu selalu membuat saya marah!
rickumali
15
@rickumali Sebagai anggota dari seluruh dunia, saya berterima kasih kepada Ruby karena menggunakan format tanggal default "kami".
Claudio Holanda
7
@rickumali Ruby juga menerima tanggal dalam YYYY-MM-DDformat, yang memang harus digunakan semua orang.
user513951
1

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

michael
sumber
5
Tanggal adalah dalam hitungan hari, jadi Anda tidak perlu melakukan ini. Saya pikir solusi Anda menjadi relevan dengan perbedaan DateTime.
suga_shane
1

Nah, jaga apa yang Anda maksud dengan "antara" juga ...

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
sumber