Storing time in rails - ruby-on-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

Related

Rails TimeWithZone and leap years

Today is Feb 29th: the day our tests broke.
Our tests are failing because these tests do things that, in the end, can be compared to a command like this: Time.zone.now - 1.year + 1.year. And it happens to be NOT equal to Time.zone.now.
Why does this happen? Why isn't ActiveSupport able to handle leap years in calculations like that? Doesn't it work with timestamps, that would prevent this sort of problem from happening?
You could use 4 years instead of 1 for the same effect. (Note: - 1.day because it is 1st March right now)
(Time.zone.now - 1.day) - 4.year + 4.year
=> Mon, 29 Feb 2016 15:12:58 UTC +00:00
It may be worth noting that (below), regardless of date.
Time.zone.now
=> Tue, 01 Mar 2016 15:11:51 UTC +00:00
Time.zone.now == Time.zone.now - 1.year + 1.year
=> false
Unless you use beginning_of_day:
(Time.zone.now - 1.day).beginning_of_day == ((Time.zone.now - 1.day) - 4.year + 4.year).beginning_of_day
=> true
Also, it depends what you are actually trying to do... Why would you want to test Time.now - 1.year + 1.year ?
Also...
1.year == 365.days
=> false
1.year == 365.25.days
=> true

Rails get difference between two dates [duplicate]

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.

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.

Ruby expression evaluation: whitespace matters?

Imagine it's Jan 19. This will not be hard if you look at this question today.
Date.today
=> Thu, 19 Jan 2012 # as expected
Date.today + 1
=> Fri, 20 Jan 2012 # as expected
Date.today+1
=> Fri, 20 Jan 2012 # as expected
Date.today +1
=> Thu, 19 Jan 2012 # ?!
What am I missing here?
The difference is that:
Date.today + 1
is an addition of two numerical values and
Date.today +1
is a call to the method today with the parameter sg(day of calendar reform) with value +1
The best way to examine this is to monkey patch the original method with debug output included. See this script as example:
require 'date'
class Date
def self.today(sg=ITALY)
puts "ITALY default("+sg.to_s+")" if sg==ITALY
puts sg unless sg==ITALY
jd = civil_to_jd(*(Time.now.to_a[3..5].reverse << sg))
new0(jd_to_ajd(jd, 0, 0), 0, sg)
end
end
puts "- Addition:"
Date.today + 1
puts "- Parameter:"
Date.today +1
This will print the following console output:
- Addition:
ITALY default(2299161)
- Parameter:
1
Yes, whitespace does matter in Ruby, contrary to popular belief. For example, foo bar is not the same as foobar.
In this particular case,
Date.today + 1
is the same as
Date.today().+(1)
Whereas
Date.today +1
is the same as
Date.today(+1)
which is the same as
Date.today(1.+#())

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