Порахуйте кількість днів між двома датами


149

Як я рахую кількість днів між цими двома датами?

start_date = Date.parse "2012-03-02 14:46:21 +0100"
end_date =  Date.parse "2012-04-02 14:46:21 +0200"

Відповіді:


207

За допомогою класів Date (та DateTime) ви можете зробити, (end_date - start_date).to_iщоб отримати різницю в кількості днів.


5
@MichaelDurrant Ви робите необґрунтоване припущення. Користувач не вказує, чи є вони рядками чи ні. Насправді, оскільки вони використовують Rails, найімовірніше, що дати надходять від ActiveRecord, який автоматично передає їх об'єктам дати. Даний текст є ідентичним представленням об'єкта Date, тому велика ймовірність, що він походить з рідного джерела.
Ендрю Франс

84
Це дає мені різницю в секундах НЕ в днях з рейками v3 / 4
2названий хаос

6
Наскільки я можу сказати, поведінка залишається однаковою у всіх останніх версіях Ruby та ActiveSupport, включаючи 2.0 та 4.1.0 відповідно. TimeОб'єкти, однак, повертають секунди.
Ендрю Франція

5
щоб розгорнути відповідь на @ 2called-haos, отримати дні, які вам знадобляться (end_date - start_date) /1.day, що дасть вам плавати. Якщо ви хотіли мати цілі дні, ви можете скористатися ((end_date
David K.

2
@David За винятком того, що коментар @ 2called-chaos помилково посилається на Timeоб'єкти, а не на Dateоб'єкти. Можливо, ви можете оновити назву у своєму коментарі, щоб відобразити, що вони не є датами?
Ендрю Франс

109

Якщо припустити , що end_dateі start_dateобидва класу ActiveSupport::TimeWithZoneв Rails, то ви можете використовувати:

(end_date.to_date - start_date.to_date).to_i

2
Якщо це стосується полів таблиці, ця відповідь - це шлях; замість найбільш оціненого тут.
Бен

Не працює (Time.zone.now.to_date - 23.hours.ago.to_date).to_i, дає 1 і має бути 0
Юрій Генцев

3
@ YuriGhensev, це залежить від того, коли ви запустите свій прикладний код, наприклад, зараз Time.zone.now.to_dateповертається "Wed, 15 Nov 2017", а 23.hours.ago.to_dateповертається "Tue, 14 Nov 2017". Різниця в кількості днів є і повинна бути 1, якщо ви не запустили свій код за годину до півночі.
лій

35

У Rails є кілька вбудованих помічників, які можуть вирішити це для вас. Слід пам’ятати, що це частина помічників Actionview, тому вони не будуть доступні безпосередньо з консолі.

Спробуйте це

<% start_time =  "2012-03-02 14:46:21 +0100" %>
<% end_time   =  "2012-04-02 14:46:21 +0200" %>
<%= distance_of_time_in_words(start_time, end_time)  %>

 "about 1 month"

@MaayanNaveh це не повинно бути, коли вам потрібна фактична кількість для розрахунків.
Федкомп

Це питання є одним із тих випадків, коли саме питання краще задавати по-іншому. Якщо ви дотримуєтесь інших відповідей тут, ви натрапите на випадки, коли іноді вам потрібні тижні чи роки, а не дні. Це дійсно слід сприймати як "правильну" відповідь Рейлса.
Ділан Пірс

34

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

(Time.now - self.created_at) / 86400

1
@Epigene 1.dayне є rubyтаким, як вимагається ОП (у тегах). Це Railsабо більш конкретно, active supportхоча created_atце в основному Modelметод в Railsтому, що ..
Roko

26

щоб отримати кількість днів у часовому діапазоні (лише кількість усіх днів)

(start_date..end_date).count
(start_date..end_date).to_a.size
#=> 32

щоб отримати кількість днів між двома датами

(start_date...end_date).count
(start_date...end_date).to_a.size
#=> 31

Дякую за це @ a14m! Дав мені спосіб зробити інклюзивні та ексклюзивні захоплення побачень :)
Кріс Бойд

18

Жодна з попередніх відповідей (до цієї дати) не дає правильної різниці в днях між двома датами.

Той, хто найближче знаходиться, знаходиться за цією данкентом . Повна відповідь перетворить, to_iа потім розділить:

(Time.now.to_i - 23.hours.ago.to_i) / 86400
>> 0

(Time.now.to_i - 25.hours.ago.to_i) / 86400
>> 1

(Time.now.to_i - 1.day.ago.to_i) / 86400
>> 1

У конкретному прикладі запитання не слід розбиратись, Dateчи пройдений час є релевантним. Використовуйте Time.parseзамість цього.


Це може не працювати, як очікувалося, коли час перетинає перехід DST, рухаючись вперед. У цьому випадку перехідна тривалість дня DST на законних підставах менше 24 годин, але через цілу арифметику цей день взагалі не відображатиметься.
PinnyM

4

Щоб мати кількість цілих днів між двома датами ( DateTimeоб'єктами):

((end_at - start_at).to_f / 1.day).floor

Те саме питання ДСТ як відповідь, який дав Юрій. Арифметика з часом ніколи не є такою простою, як ви очікували :)
PinnyM

0

Щоб отримати різницю числа днів на дві дати:

(start.to_date...end.to_date).count - 1
or 
(end.to_date - start.to_date).to_i

-8
def business_days_between(date1, date2)
  business_days = 0
  date = date2
  while date > date1
   business_days = business_days + 1 unless date.saturday? or date.sunday?
   date = date - 1.day
  end
  business_days
end

3
набагато простіше відняти об’єкти дати.
OpenCoderX

ОП ніколи не питала про коригування на робочі дні. Це все-таки суперечить.
Натан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.