SundayMonday
SundayMonday

Reputation: 19737

Number of days between two Time instances

How can I determine the number of days between two Time instances in Ruby?

> earlyTime = Time.at(123)
> laterTime = Time.now
> time_difference = laterTime - earlyTime

I'd like to determine the number of days in time_difference (I'm not worried about fractions of days. Rounding up or down is fine).

Upvotes: 27

Views: 24117

Answers (8)

Marian13
Marian13

Reputation: 9248

in_days (Rails 6.1+)

Rails 6.1 introduces new ActiveSupport::Duration conversion methods like in_seconds, in_minutes, in_hours, in_days, in_weeks, in_months, and in_years.

As a result, now, your problem can be solved as:

date_1 = Time.parse('2020-10-18 00:00:00 UTC')
date_2 = Time.parse('2020-08-13 03:35:38 UTC') 

(date_2 - date_1).seconds.in_days.to_i.abs
# => 65

Here is a link to the corresponding PR.

Upvotes: 4

Here is a simple answer that works across DST:

numDays = ((laterTime - earlyTime)/(24.0*60*60)).round

60*60 is the number of seconds in an hour 24.0 is the number of hours in a day. It's a float because some days are a little more than 24 hours, some are less. So when we divide by the number of seconds in a day we still have a float, and round will round to the closest integer.

So if we go across DST, either way, we'll still round to the closest day. Even if you're in some weird timezone that changes more than an hour for DST.

Upvotes: 3

stevo999999
stevo999999

Reputation: 608

None of these answers will actually work if you don't want to estimate and you want to take into account daylight savings time. For instance 10 AM on Wednesday before the fall change of clocks and 10 AM the Wednesday afterwards, the time between them would be 1 week and 1 hour. During the spring it would be 1 week minus 1 hour. In order to get the accurate time you can use the following code

def self.days_between_two_dates later_time, early_time
   days_between = (later_time.to_date-early_time.to_date).to_f
   later_time_time_of_day_in_seconds = later_time.hour*3600+later_time.min*60+later_time.sec
   earlier_time_time_of_day_in_seconds = early_time.hour*3600+early_time.min*60+early_time.sec
   days_between + (later_time_time_of_day_in_seconds - early_time_time_of_day_in_seconds)/1.0.day   
end

Upvotes: 2

Kamil Lelonek
Kamil Lelonek

Reputation: 14754

[1] pry(main)> earlyTime = Time.at(123)
=> 1970-01-01 01:02:03 +0100
[2] pry(main)> laterTime = Time.now
=> 2014-04-15 11:13:40 +0200
[3] pry(main)> (laterTime.to_date - earlyTime.to_date).to_i
=> 16175

Upvotes: 5

ambivalence
ambivalence

Reputation: 252

To account for DST (Daylight Saving Time), you'd have to count it by the days. Note that this assumes less than a day is counted as 1 (rounded up):

num = 0
cur = start_time
while cur < end_time
  num += 1
  cur = cur.advance(:days => 1)
end
return num

Upvotes: 4

Phrogz
Phrogz

Reputation: 303271

require 'date'
days_between = (Date.parse(laterTime.to_s) - Date.parse(earlyTime.to_s)).round

Edit ...or more simply...

require 'date'
(laterTime.to_date - earlyTime.to_date).round

Upvotes: 19

James Brooks
James Brooks

Reputation: 658

earlyTime = Time.at(123)
laterTime = Time.now
time_difference = laterTime - earlyTime
time_difference_in_days = time_difference / 1.day  # just divide by 1.day

Upvotes: 12

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230396

Difference of two times is in seconds. Divide it by number of seconds in 24 hours.

(t1 - t2).to_i / (24 * 60 * 60)

Upvotes: 49

Related Questions