This project is archived and is in readonly mode.
Glitch in DateHelper with timezones (#time_ago_in_words causing "undefined method 'abs'")
Reported by epitron | November 10th, 2009 @ 09:51 AM
After I enabled Rails' new TimeZone features, I got this error in an obscure set of circumstances:
ActionView::TemplateError (undefined method `abs' for Thu Feb 19 13:59:51 -0500 1970:Time)
(The exception is is thrown by DateHelper#distance_of_time_in_words, called fromDateHelper#time_ago_in_words... it's not in the backtrace, but I confirmed it in a debugger.)
It appears that Time objects and ActiveSupport::TimeWithZone objects are getting mixed together, and when you try to take their difference, the resulting object doesn't always have an #abs method.
To fix it, I just patched #time_ago_in_words to use "Time.zone.now" instead of "Time.now":
module ActionView::Helpers::DateHelper
def time_ago_in_words(from_time, include_seconds = false)
distance_of_time_in_words(from_time, Time.zone.now, include_seconds)
end
end
But this is a nasty hack. :)
Perhaps the default Time objects (DateTime, Time, etc.) should be patched to always return ActiveSupport::TimeWithZone objects when timezones are enabled?
(Rails version: 2.3.4)
Comments and changes to this ticket
-
Geoff Buesing November 10th, 2009 @ 02:36 PM
- Assigned user set to Geoff Buesing
I can't replicate this.
With what arguments are you calling time_ago_in_words to get the error?
-
epitron November 10th, 2009 @ 09:45 PM
The problem seems to stem from creating an ActiveSupport::TimeWithZone from a DateTime object:
d = DateTime.parse("jan 7").in_time_zone
If you go to the console, you'll notice that Time.now - d returns a Time object (no #abs), whereas Time.now - another_time_object gives you an integer.
-
Geoff Buesing November 10th, 2009 @ 10:22 PM
- State changed from new to open
Aha, ok, I see what the issue is -- the instance of ActiveSupport::TimeWithZone you're creating is storing the time internally as a DateTime (because you started with DateTime.parse), and Time#- with a DateTime instance as an argument returns another instance of Time, instead of a Float.
The fix should be easy enough -- we'll just need to add additional logic to Time#minus_with_coercion so that it returns a Float instead of a Time when a DateTime arg is supplied.
The current Time#- behavior with a DateTime arg seems very broken, so I see no issues with fixing it -- see example below, I have no idea how anyone could be relying on this behavior:
>> Time.local(2009,1,2) - DateTime.civil(2009,1,1) => Fri Jan 02 00:00:00 -0600 1970
-
Repository January 28th, 2010 @ 02:18 AM
(from [e98f9579c472e75f5a8c0678f2fc54b2d681e3ec]) Time#- with a DateTime argument behaves the same as with a Time argument, i.e. returns the difference between self and arg as a Float [#3476 status:resolved] http://github.com/rails/rails/commit/e98f9579c472e75f5a8c0678f2fc54...
-
Repository January 28th, 2010 @ 02:25 AM
(from [3f7729a66eeb362d6d4f7b0add6ca40151794b74]) Time#- with a DateTime argument behaves the same as with a Time argument, i.e. returns the difference between self and arg as a Float [#3476 status:resolved] http://github.com/rails/rails/commit/3f7729a66eeb362d6d4f7b0add6ca4...
-
Geoff Buesing January 28th, 2010 @ 02:27 AM
Turns out the standard library isn't to blame -- ActiveSupport defines DateTime#to_f, so Time#- coerces the DateTime arg #to_f and assumes we're subtracting seconds, instead of finding the difference between two times.
-
Geoff Buesing January 28th, 2010 @ 02:31 AM
- State changed from open to resolved
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Referenced by
- 3476 Glitch in DateHelper with timezones (#time_ago_in_words causing "undefined method 'abs'") (from [e98f9579c472e75f5a8c0678f2fc54b2d681e3ec]) Time#- ...
- 3476 Glitch in DateHelper with timezones (#time_ago_in_words causing "undefined method 'abs'") (from [3f7729a66eeb362d6d4f7b0add6ca40151794b74]) Time#- ...