Rails get difference between two dates [duplicate] - ruby-on-rails

This question already has answers here:
How to evaluate a date difference in years, months and days (ruby)?
(6 answers)
Closed 8 years ago.
How to get time difference in days,hours,mins
I am trying to do
datetime_A - datetime_B
datetime_A = Sat, 04 Jan 2014 07:00:13 +0000
datetime_B = Fri, 03 Jan 2014 01:09:46 +0000
it returns me something like(35809/28800),bdw what does it means?
I need like 1day,5h,23min
How can do it?

You need to add helper in your rails app to achive this. Ruby not provide any direct way for this. Below is date manipulation using ruby 2.1.0.
2.1.0 :021 > a_date_time = DateTime.now
=> Fri, 26 Dec 2014 16:39:30 +0530 # First Date
2.1.0 :022 > b_date_time = DateTime.now-20
=> Sat, 06 Dec 2014 16:40:03 +0530 # Second Date
2.1.0 :023 > (a_date_time - b_date_time).to_i
=> 19 # Direct date difference
2.1.0 :024 > Seconds = ((a_date_time - b_date_time)*24*60*60).to_i
=> 1727966 # Seconds between two dates
2.1.0 :025 > sec = Seconds % 60
=> 26 # Second diffence to print
2.1.0 :026 > Minutes = Seconds / 60
=> 28799 # Minutes between two dates
2.1.0 :027 > min = Minutes % 60
=> 59 # Minute diffence to print
2.1.0 :028 > Hours = Minutes / 60
=> 479 # Hours between two dates
2.1.0 :029 > hour = Hours % 24
=> 23 #Hour diffence to print
2.1.0 :030 > Days = Hours / 24
=> 19 # Days between two dates
2.1.0 :032 > Days.to_s + 'Days, ' + hour.to_s + 'Hours, '+ min.to_s + 'Mins, ' + sec.to_s + 'Secs'
=> "19Days, 23Hours, 59Mins, 26Secs" # Desired output

An alternative could be to use the ActionView helper distance_of_time_in_words (see the documentation). If normally does not give the exact minor units, but something like "around 5 days".

I like to use the gem time_diff
https://github.com/abhidsm/time_diff
Here is a example how it works
Time.diff(Time.parse('2011-03-06'), Time.parse('2011-03-07'))
# => {:year => 0, :month => 0, :week => 0, :day => 1, :hour => 0, :minute => 0, :second => 0, :diff => '1 day and 00:00:00'}

The value that is being given is a Rational, (http://www.ruby-doc.org/core-2.1.5/Rational.html). It represents the number of days between the two dates. This is actually quite cool, as it can be much more accurate than a float and easily convertible to hours, minutes, seconds etc.

Related

Storing time in rails

I want to store a date 3 months from the current date and put it into current_user.expiry_date.
current_user.expiry_date = Date.today + 3.months
I'm new to doing dates but is this sufficient? expiry_date is of data type date. This would give an expiry date 3 months after this attribute is set. Anything wrong with this?
That looks fine to me. It should give you the date 3 months from now.
irb(main):001:0> require 'active_support/all'
=> true
irb(main):002:0> Date.today + 3.months
=> Mon, 21 Nov 2016
irb(main):003:0> (Date.today + 3.months).class
=> Date

Number of hours between two dates - Ruby

Say I want the difference between tomorrow and now (in hours).
What I've tried:
t = (DateTime.tomorrow - DateTime.now)
(t / 3600).to_i
=> 0
Why does it give 0?
What am I doing wrong?
This is because DateTime.tomorrow does not have any time value. Here:
DateTime.tomorrow
# => Wed, 22 Apr 2015
If you go through official document for DateTime you can see there is no method tomorrow. Its basically Date#tomorrow.
You can use .to_time to get default localtime 00:00:00
DateTime.tomorrow.to_time
# => 2015-04-22 00:00:00 +0530
(DateTime.tomorrow.to_time - DateTime.now) / 1.hours
# => 9.008116581638655
To get exact hour difference between dates:
(DateTime.tomorrow.to_time - Date.today.to_time) / 1.hours
# => 24.0
Try this
t = (DateTime.tomorrow.to_time - Date.today.to_time)
t = (t / 3600).to_i
It returns rational number. You can take days number if you'll use round method:
>> (DateTime.tomorrow - DateTime.now).round
1
Or if you want to take value in hours from now, use Time class:
>> (Date.tomorrow.to_time - Time.now) / 1.hour
11.119436663611111
if you have two dates like
start_time = Time.new(2015,1, 22, 35, 0)
end_time = Time.new(2015,2, 22, 55, 0)
Try Time Difference gem for Ruby at https://rubygems.org/gems/time_difference
def timediff(start, end)
TimeDifference.between(start, end).in_hours
end
and call it like:
timediff(start_time, end_time)
It will work.
Cheers!
There's DateTime#seconds_until_end_of_day:
seconds = DateTime.now.seconds_until_end_of_day
#=> 41133
seconds / 3600
#=> 11
distance_of_time_in_words(seconds)
=> "about 11 hours"

Difference between two datetimes not showing in days, it shows me in seconds instead, I have used timezone as IST

Im working on a small Rails application. I have set my timezone to IST by changing my config file to
config.time_zone = 'Kolkata'
I have a model which takes a virtual attribute Subscription and converts in into two datetimes valid_from and valid_to, The code is as follows:
def subscription=(value)
case value
when "WEEKLY"
self.valid_from = DateTime.now
self.valid_to = DateTime.now + 7.days
when "MONTHLY"
self.valid_from = DateTime.now
self.valid_to = DateTime.now >> 1
when "HALF YEARLY"
self.valid_from = DateTime.now
self.valid_to = DateTime.now >> 6
when "YEARLY"
self.valid_from = DateTime.now
self.valid_to = DateTime.now >> 12
end
end
It stores the values perfectly, but when I retrieve the number of days its giving me wrong days. i have tried it out in console to show the results, Here are the results:
irb(main):017:0> x = a.valid_from
=> Wed, 16 Apr 2014 14:15:04 IST +05:30
irb(main):018:0> y = a.valid_to
=> Wed, 23 Apr 2014 14:15:04 IST +05:30
irb(main):019:0> z = DateTime.now
=> Wed, 16 Apr 2014 14:19:07 +0530
irb(main):020:0> w = DateTime.now + 7.days
=> Wed, 23 Apr 2014 14:19:28 +0530
irb(main):021:0> p = (y-x).to_i
=> 604800
irb(main):022:0> q = (w-z).to_i
=> 7
irb(main):023:0> Time.zone
=> (GMT+05:30) Mumbai
I can see the difference in times in mine it shows IST + 5:30 and in DateTime.now it just shows +5:30. But I dont know why that is happening. I'm new to rails and if someone could let me know about it I will be very grateful.
Also i tried to decode the value 604800. I guessed that it has to be something x*7 and so I got the value of x to be 86400.
Now 86400 = 24*60*60. This implies I have been getting the value in seconds. Can I know why this is happening? I would like to get it in days.

Difference between Rails 2.3 and Rails 3.2 'weeks' method

I've noticed some different behaviour between Rails 2 and Rails 3 when it comes to ActiveSupport date handling.
When I run the following code in a Rails 2.3 application it runs as I expect and outputs the dates one week at a time.
>> first = Date.today
=> Fri, 23 Mar 2012
>> last = Date.today + 2.months
=> Wed, 23 May 2012
>> first.step(last, 1.week) { |date| puts date }
2012-03-23
2012-03-30
2012-04-06
2012-04-13
2012-04-20
2012-04-27
2012-05-04
2012-05-11
2012-05-18
When I try the same code within a Rails 3 application I get the following.
>> first = Date.today
=> Fri, 23 Mar 2012
>> last = Date.today + 2.months
=> Wed, 23 May 2012
>> first.step(last, 1.week) { |date| puts date }
Mar 23, 2012
TypeError: expected numeric
The problems seems to be with how Rails 3 is now handling the .weeks method, Rails 2 outputs the following
>> 1.week
=> 7 days
Where Rails 3 outputs
>> 1.week
=> 604800
Can anyone explain what is going on here and how I can neatly iterate over a date range one week at a time in Rails 3.
No idea why it doesn't work, but this seems to:
(Date.today..(Date.today + 30)).step(7)

How to add minutes to a Time object

In Ruby, how do I do Time.now + 10.hours?
Is there an equivalent for secs and mins? For example:
Time.now + 15.mins
Ruby (the programming language) doesn't have 10.hours, that's ActiveSupport as part of Ruby on Rails (the web framework). And yes, it does have both minutes and seconds methods.
However, Time#+ (the + method on Time instances) returns a new Time instance that is that many seconds in the future. So without any Ruby on Rails sugar, you can simply do:
irb> t = Time.now
#=> 2011-08-03 22:35:01 -0600
irb> t2 = t + 10 # 10 Seconds
#=> 2011-08-03 22:35:11 -0600
irb> t3 = t + 10*60 # 10 minutes
#=> 2011-08-03 22:45:01 -0600
irb> t4 = t + 10*60*60 # 10 hours
#=> 2011-08-04 08:35:01 -0600
If you are using ActiveSupport, what you are looking for is the full .minutes and .seconds.
Time.now + 10.minutes
Time.now + 10.seconds
Also in ActiveSupport you can do:
10.minutes.from_now
10.minutes.ago
I think you're talking about extensions added by Rails. I think you need 15.minutes.
See the Active Support Core Extensions for Date, DateTime and Time for more information.
Time Object
time = Time.now
Adding minutes to a time object:
time + 5.minutes
There is an advance function in Active Support refer.
You can do the following using advance:
d = DateTime.new(2010, 2, 28, 23, 59, 59)
=> Sun, 28 Feb 2010 23:59:59 +0000
d.advance(hours: 1)
=> Mon, 01 Mar 2010 00:59:59 +0000

Resources