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


141

Bagaimana saya bisa menemukan jumlah hari antara dua objek Date?

Jawaban:


170

Kurangi tanggal mulai dari tanggal akhir:

endDate - beginDate 

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.


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 

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 

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.


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



6

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

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

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)


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.