Як я можу знайти кількість днів між двома об'єктами Date в Ruby?


141

Як я можу знайти кількість днів між двома об’єктами дати?

Відповіді:


170

Відняти дату початку від кінцевої дати:

endDate - beginDate 

2
Ви думаєте, ви маєте на увазі відняти дату початку від дати закінчення :)
Надер

99
вид антикліматичної е?
Бриг

18
зауважте: якщо ви використовуєте Wirble в irb (щоб розфарбувати висновок), раціональне число матиме 1 зв'язаний до кінця. поступається! ви можете скористатися to_i для перетворення результату в ціле число
jwal

9
Якщо у вас є DateTimeоб'єкт, не забудьте перетворити його на Dateперший, інакше він поверне кількість секунд (я думаю).
Джошуа Мухайм

44
також зауважте, що віднімання двох Dateоб'єктів дає вам Rationalте, що вам може знадобитися ввести ціле число, як це (endDate - beginDate).to_i
стосується

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

Тут використовується модифікований Джуліанський номер .

З Вікіпедії :

Юліанська дата (JD) - інтервал часу в днях і частках дня з 1 січня 4713 року до н.е., полудень Грінвіч, Юліанський пролептичний календар.


53

Це може змінитися в Ruby 2.0

Коли я це роблю, я отримую дріб. Наприклад, на консолі (або вкладку, або рейки 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) 

Звичайно, кастинг до int дає очікуваний результат

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

Це також працює для об’єктів DateTime, але вам потрібно врахувати секунди, наприклад, цей приклад

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

У Ruby 2.1.3 все змінилося:

> 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

Як щодо цього?

(beginDate...endDate).count

Діапазон - це набір унікальних серіалів. І ...це ексклюзивний діапазон літерал.

Так beginDate..(endDate - 1)само. За винятком ні.

У випадку, коли startDate дорівнює endDate , перший елемент буде виключений через унікальність і ...виключить останній. Тож якщо ми хочемо .countпобачити дати сьогодні і сьогодні, це поверне 0.


Це дуже хороша відповідь, якщо startDate старший за endDate, він повернеться 0, що прекрасно працює в деяких випадках. Крім того, якщо дві дати однакові, він поверне 0. Він також поверне просте ціле число. Інші відповіді повинні бути перетворені на цілі числа або, можливо, вам доведеться перевести 0, якщо результат негативний.
EmmanuelB



6

все це спрямовувало мене на правильний результат, але я закінчував це

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

Один елемент, який слід зазначити: DateTime.parse в Ruby очікує, що дата буде вказана як DD / MM / РРРР або DD-MM-YYYY. Як американець, мене завжди відкидає!
rickumali

15
@rickumali Як учасник з усього світу, я дякую Рубі за те, що він використовував "наш" формат дати за замовчуванням.
Клаудіо Голландія

7
@rickumali Ruby також приймає дату у YYYY-MM-DDформаті, і це все, що всі повинні використовувати.
user513951

1

днів = (endDate - beginDate) / (60 * 60 * 24)


5
Дата розрахована на дні, тому не потрібно цього робити. Я думаю, що ваше рішення стає актуальним у випадку відмінностей DateTime.
suga_shane

1

Ну, подбайте про те, що ви маєте на увазі під "між" теж ...

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.