DateTime formatting Rails - ruby

I have "Date.today + 2.days" I need to format it using .strftime, but with the "+2.days" it doesn't recognize that method.Any ideas?

Those nice helpers don't come with a vanilla ruby install. You need the activesupport gem (part of Ruby on Rails).
$ gem install activesupport
$ irb
ruby-1.8.7-p249 > require 'rubygems'
=> true
ruby-1.8.7-p249 > require 'active_support'
=> true
ruby-1.8.7-p249 > Date.today
=> Fri, 16 Jul 2010
ruby-1.8.7-p249 > Date.today + 2.days
=> Sun, 18 Jul 2010

I don't see a problem, worked fine for me.
(Date.today + 2.days).strftime
#=> "2010-07-18"

Related

Loading help documentation alters irb results

I'm learning Ruby, and went into irb to test something out with the Date class. In short, I did the following:
$ irb
irb(main):001:0> Date.new
=> #<Date:0x007f983103ee60>
irb(main):002:0> Date.constants
=> []
irb(main):003:0> help Date
=> nil
irb(main):004:0> Date.constants
=> [:MONTHNAMES, :ABBR_MONTHNAMES, :DAYNAMES, :ABBR_DAYNAMES, :ITALY, :ENGLAND, :JULIAN, :GREGORIAN, :Infinity]
irb(main):005:0>
I'm so confused by this. Questions:
Why would reading help documentation cause the output of Date.constants to change?
Presumably help is loading/initializing something. What is it? And why did Date.new work?
Is whatever this is something I need to worry about when writing .rb files?
This is tough to Google for. I'm on ruby 2.1.2 and irb 0.9.6.
The most likely cause of the addition of the Date constants after running help Date is that somewhere in the execution of the command, require 'date' (or require 'time') is called:
2.1.0 :001 > Date.constants
=> []
2.1.0 :002 > require 'date'
=> true
2.1.0 :003 > Date.constants
=> [:MONTHNAMES, :ABBR_MONTHNAMES, :DAYNAMES, :ABBR_DAYNAMES, :ITALY, :ENGLAND, :JULIAN, :GREGORIAN, :Infinity]
As for Date.new, it works because Date comes with a default constructor.
I doubt this will ever be problematic for you.

ruby DateTime parsing from 'mm/dd/yyyy' format

I am using ruby 1.9.3 and want to get Date or Time object from 'mm/dd/yyyy' date format string
Time.zone.parse("12/22/2011")
this is giving me *** ArgumentError Exception: argument out of range
require 'date'
my_date = Date.strptime("12/22/2011", "%m/%d/%Y")
As above, use the strptime method, but note the differences below
Date.strptime("12/22/2011", "%m/%d/%Y") => Thu, 22 Dec 2011
DateTime.strptime("12/22/2011", "%m/%d/%Y") => Thu, 22 Dec 2011 00:00:00 +0000
Time.strptime("12/22/2011", "%m/%d/%Y") => 2011-12-22 00:00:00 +0000
(the +0000 is the timezone info, and I'm now in GMT - hence +0000. Last week, before the clocks went back, I was in BST +0100. My application.rb contains the line config.time_zone = 'London')
Try Time.strptime("12/22/2011", "%m/%d/%Y")
Would it be an option for you to use Time.strptime("01/28/2012", "%m/%d/%Y") in place of Time.parse? That way you have better control over how Ruby is going to parse the date.
If not there are gems: (e.g. ruby-american_date) to make the Ruby 1.9 Time.parse behave like Ruby 1.8.7, but only use it if it's absolutely necessary.
1.9.3-p0 :002 > Time.parse '01/28/2012'
ArgumentError: argument out of range
1.9.3-p0 :003 > require 'american_date'
1.9.3-p0 :004 > Time.parse '01/28/2012'
=> 2012-01-28 00:00:00 +0000

Ruby Time.zone.now.zone bug

What I mean is that there are different timezones with the same name, like CST (-06:00 in US and +09:30 in Australia). Accordingly conversion to utc gives wrong results for Adelaide.
Any elegant way to solve this?
an easy way would be that you use the other nomenclature of naming time zones..
e.g. for UTC+9:30 intstead of using CST, you can use "Australia/Adelaide"
tz = TZInfo::Timezone.get("Australia/Adelaide")
t = Time.now # you could also get the UTC time here with Time.now.utc
t.zone
=> "PDT"
t.utc_offset
=> -25200
t.in_time_zone(tz) # this is a Rails extension of the Time class
=> Sat, 01 Oct 2011 14:31:05 CST +09:30
t.in_time_zone(tz).zone
=> "CST"
t.in_time_zone(tz).utc_offset
=> 34200
See:
http://api.rubyonrails.org/classes/Time.html
http://tzinfo.rubyforge.org/doc/
http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
do a "gem install activesupport", and in your script:
require 'rubygems'
require 'tzinfo'
require 'active_support'

Ruby Date Subtraction (e.g. 90 days Ago)

I've been a bit spoiled by the joda-time API of:
DateTime now = new DateTime();
DateTime ninetyDaysAgo = now.minusDays(90);
I'm trying to do a similar thing in Ruby, but I'm
now = Time.now
ninetyDaysAgo = now - (90*24)
However, the math is off here (I'm really working with dates at midnight).
Is there friendly API for date subtraction?
require 'date'
now = Date.today
ninety_days_ago = (now - 90)
Running this thru the IRB console I get:
>>require 'date'
now = Date.today
ninety_days_ago = (now - 90)
require 'date'
=> false
now = Date.today
=> #<Date: 2011-03-02 (4911245/2,0,2299161)>
ninety_days_ago = (now - 90)
=> #<Date: 2010-12-02 (4911065/2,0,2299161)>
If you need the time you could just say now = DateTime.now
For those using Rails, check out the following:
DateTime.now - 10.days
=> Sat, 04 May 2013 12:12:07 +0300
20.days.ago - 10.days
=> Sun, 14 Apr 2013 09:12:13 UTC +00:00
If you're using Rails or don't mind including ActiveSupport, you can use the Numeric#days DSL like this:
ruby-1.9.2-p136 :002 > Date.today
=> Wed, 02 Mar 2011
ruby-1.9.2-p136 :003 > Date.today - 90.days
=> Thu, 02 Dec 2010
Since you are working with dates instead of times, you should also either start with Date instances, or convert your DateTime intances with #to_date. When adding/subtracting numbers from date instances, the numbers are implicitly days.
ruby-1.9.2-p136 :016 > DateTime.now.to_date
=> #<Date: 2011-03-02 (4911245/2,0,2299161)>
ruby-1.9.2-p136 :017 > DateTime.now.to_date - 90
=> #<Date: 2010-12-02 (4911065/2,0,2299161)>
Ruby supports date arithmetic in the Date and DateTime classes, which are part of Ruby's standard library. Both those classes expose #+ and #- methods, which add and subtract days from a date or a time.
$ irb
> require 'date'
=> true
> (DateTime.new(2015,4,1) - 90).to_s # Apr 1, 2015 - 90 days
=> "2015-01-01T00:00:00+00:00"
> (DateTime.new(2015,4,1) - 1).to_s # Apr 1, 2015 - 1 day
=> "2015-03-31T00:00:00+00:00"
Use the #<< and #>> methods to operate on months instead of days. Arithmetic on months is a little different than arithmetic on days. Using Date instead of DateTime makes the effect more obvious.
> (Date.new(2015, 5, 31) << 3).to_s # May 31 - 3 months; 92 days diff
=> "2015-02-28"
Following your joda-time example, you might write something like this in Ruby.
now = DateTime.now
ninety_days_ago = now - 90
or maybe just
ninety_days_ago = DateTime.now - 90
use the number of seconds:
Time.now - 90*24*60*60
This is a super old post, but if you wanted to keep with a Time object, like was originally asked, rather than switching to a Date object you might want to consider using Ruby Facets.
Ruby Facets is a standardized library of extensions for core Ruby classes.
http://rubyworks.github.io/facets/
By requiring Facets you can then do the following with Time objects.
Time.now.less(90, :days)
Simple solution using Rails Active Support:
days90_ago = 90.days.ago.to_date.to_s
OUTPUT:
puts 90_days_ago
=> "2019-10-09" # considering cur_date: 2020-01-07

Rails 2.3.2, wrong date, system date is correct

ruby-1.8.6-p399 :005 > Date.today
=> Wed, 24393 Dec 2135
ruby-1.8.6-p399 :006 > DateTime.now
=> Wed, 24393 Dec 2135 17:07:09 +0100
wopi#wopi-desktop:~/work/trunk$ date
Mi 2. Feb 17:08:46 CET 2011
What's wrong ?
https://gist.github.com/807916
What do you get with: Time.at(0) ?
Should be 1969...
What do you get with Time.now?
The date objects come from the date class, which inherits from the time class:
http://corelib.rubyonrails.org/classes/Time.html
Other helpful methods to test could be there. Try doing straight ruby to see if it's a problem with your rails setup or with ruby. You should be able to trace the specific place where this goes wrong.

Resources