How to add minutes to a Time object - ruby-on-rails

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

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 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)

Override what Ruby thinks is the current time in Time.now?

I want to create test data for an application, and there are a lot of time_at attributes being tracked, too many to override in a maintainable way. What I'm thinking is, can I just change the base reference time variable in Ruby?
This would make it so created_at, updated_at, last_login_at, etc., could be set to an artificial time, so I could do this in tests:
Date.today #=> Thu, 30 Dec 2010
Time.system_time_offset = 1.week.ago # made up
Date.today #=> Thu, 23 Dec 2010
Time.now #=> Thu Dec 23 14:08:38 -0600 2010
user_1 = User.create!
user_1.created_at #=> Thu Dec 23 14:08:38 -0600 2010
Time.reset_system_time # made up
user_2 = User.create!
user_1.created_at #=> Thu Dec 30 14:08:38 -0600 2010
Is there a way to do this?
You could use Mocha to change the return value of Time.now during a test:
Time.stubs(:now).returns(Time.now - 1.day)
A good gem for this is Timecop: https://github.com/travisjeffery/timecop.
You can freeze time or change the time (while it continues to progress) very easily.
Ex.
Time.now
# => 2014-03-14 13:17:02 -0400
Timecop.travel 2.hours.ago
Time.now
# => 2014-03-14 11:17:04 -0400
Its nicer than the mocha solution since all time functions will be affected equally, so you won't have a test where Time.now is returning something different then DateTime.now
Its also more up-to-date than the time-warp gem suggested in another answer.
I use the timewarp gem for this sort of thing. You just put your code in a pretend_now_is(time) block and the code inside will be executed as if that was the actual time.
http://github.com/harvesthq/time-warp
Here's an example
def test_should_find_company_needing_reminded_today
pretend_now_is(Time.utc(2008,"jul",24,20)) do #=> Thu Jul 24 20:00:00 UTC 2008
#company.reminder_day = 'Thursday'
#company.save
companies = Company.find_companies_needing_reminded_today
assert_equal true, companies.include?(#company)
end
end
Honestly, I usually write tests for current time to check if the timestamp is within a reasonable range. i.e., check if the timestamp is greater than 1.minute.ago. Changing the system clock is likely to have all kinds of unpredictable side-effects, so you don't want to do that. You might be able to track down all the places in Ruby where the current time is accessed (though I think most methods just use Time.now) and monkey-patch them for the tests, but I'd probably still prefer just checking the timestamp is within a sane range.
It's also possible to (yuck) monkeypatch Time:
$start = Time.now - 86400 # this time yesterday
class Time
class << Time
def new
$start
end
def now
Time.new
end
end
end
puts(Time.now)
puts($start)

Add seconds (in fixnum format) to a datetime, Rails

I need to pass a variable to my view with Time.now + #seconds in time format (i.e. 12pm + 3600 seconds = 1:00pm, which goes to the view).
Time.now + #seconds #seconds is a fixnum
doesn't work because "Time can't be coerced into Fixnum". How then can I generate this simple result?
Don't barbeque me if this is wrong now but back when I was doing Rails you would just say Time.now + #seconds.seconds . Also #seconds.seconds.from_now
Today I learned that (1.second + DateTime.now) != (DateTime.now + 1.second)
to answer your question try using Time.now + #seconds.seconds or Time.now + #seconds.to_i.seconds
Another example
DateTime.current + 20.seconds
=> Mon, 11 Jan 2021 18:06:04 +0000

Resources