I’m porting an old rails app to Rails 4 and got stumped tonight on time
conversions.
This worked:
Loading development environment (Rails 2.3.18)
Time.now.to_s
=> “08/14/2013 07:09PM”
Time.now.to_s.to_time
=> Wed Aug 14 19:09:00 UTC 2013
Now it doesn’t on Rails 4.0:
Loading development environment (Rails 4.0.0)
irb(main):001:0> Time.now
=> 2013-08-15 00:19:48 -0500
irb(main):002:0> Time.now.to_s
=> “08/15/2013 12:19AM”
irb(main):003:0> Time.now.to_s.to_time
ArgumentError: argument out of range
from
/usr/local/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/core_ext/string/conversions.rb:23:in initialize' from /usr/local/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/core_ext/string/conversions.rb:23:innew’
If it were a simple single string I was parsing, I could do a custom one
off parse and be done with it, but this is site wide. Passing entire
hashes
to models is causing this error to manifest its self.
Any ideas to get Rails 4.0 to not just produce a custom Time string but
parse the same way as well? Seems like it should be simple, but perhaps
it’s just getting late here. ;’)
If it were a simple single string I was parsing, I could do a custom one off
parse and be done with it, but this is site wide. Passing entire hashes to models
is causing this error to manifest its self.
Any ideas to get Rails 4.0 to not just produce a custom Time string but parse
the same way as well? Seems like it should be simple, but perhaps it’s just
getting late here. ;')
Thanks!
This isn’t a Rails problem, it’s something that happens in Ruby. I think
it’s a bug:
$ irb -r date
irb(main):001:0> format = “%m/%d/%Y”
=> “%m/%d/%Y”
irb(main):002:0> Date.parse(Date.today.strftime(format),format)
ArgumentError: invalid date
from (irb):2:in parse' from (irb):2 from /Users/tamara/.rubies/ruby-2.0.0-p427/bin/irb:12:in ’
irb(main):003:0> Date.today.strftime(format)
=> “08/18/2013”
irb(main):004:0> Date.parse(Date.today.to_s)
=> #<Date: 2013-08-18 ((2456523j,0s,0n),+0s,2299161j)>
I don’t have anything older to check this on, however, reading the
system documentation for strptime(), it seems to state that formats
should be compatible with strftime().
A quick test in C[1] shows that the format from strftime to strptime is
compatible. So sounds like a ruby bug
That causes Rails 4.0/Ruby 2.0 to eat its self when dealing with forms
that have dates/times. I’m not calling Date or Time directly in this
case. I’m just letting Rails populate forms and then parse the params
on submission to update a model. It is outputting the correct format,
but it can’t seem to parse what it is outputting. This wasn’t a problem
with Rails 2.3/Ruby 1.8.7.
A simple way to manifest the problem is to do “Time.now.to_s.to_time” or
“Date.today.to_s.to_date”. This works on Rails 2.3/Ruby 1.8.7, but does
not on Rails 4.0/Ruby 2.0 with the above initializers.
It is hard to believe that they removed such basic functionality?
Tamara suggests this might be a Ruby bug(?).
=> Wed Aug 14 19:09:00 UTC 2013
from
/usr/local/lib/ruby/gems/2.0.0/gems/activesupport-4.0.0/lib/active_support/core_ext/string/conversions.rb:23:in
`initialize’
=> “2013-08-15 00:32:07 -0500”
Thanks! Yes, I did update to Ruby 2.0.0p247, but I also updated to
Rails-4 and, well, entirely new hardware and OS as well, so I’m not sure
where the bug is exactly.
See my previous comment; that format IS NOT VALID in Ruby 1.9.x and
above. Your issue has nothing to do with Rails.
A simple way to manifest the problem is to do “Time.now.to_s.to_time” or
“Date.today.to_s.to_date”. This works on Rails 2.3/Ruby 1.8.7, but does
not on Rails 4.0/Ruby 2.0 with the above initializers.
It works fine with VALID formats. Change your initializer to ‘%d/%m/%Y’
and try Date.today.to_s.to_date – no problem.
It is hard to believe that they removed such basic functionality?
Tamara
The documentation, however, points to the libc functions, strftime(3)
and strptime(3), which state quite plainly that these formats are
reflexive. Hardly seems sporting, does it? Without including a format
field, it’s probably quite reasonable to assume the parse methods will
interpret in that dd/mm/yyyy order, BUT, with a format field?? They
should not ignore the format field in that case. That is the bug.
On Wednesday, August 21, 2013 7:18:35 AM UTC-7, Hassan S. wrote:
suggests this might be a Ruby bug(?).
No. It is documented behavior of Ruby.
Don’t get me wrong, I appreciate your help!
It just seems that this was functionality that seemed to have been
broken.
It’s not a ‘valid’ vs. invalid argument (where I live, m/d/y is valid
and
d/m/y is not!) I should be able to define 1/13/2 as being Feb 1st, 2013
if
I want to be crazy about it. String parsing isn’t hard, it just seems
to
be eluding me as how to hint Rails 4/Ruby 2 on how to do it the way I
want
when it worked in the past.
As Tamara suggests, it appears the format string is being dropped by the
time it makes it to the parsing function(?). d/m/y is fine as a
default,
but saying to change my initializer to match the already default is like
removing it all together and doesn’t solve my localization problem.