A Variation On Rails' Verbose Time Helper
Oh tax season. Does anyone else find that January is the busiest month of the year?
A client of ours recently wanted a custom version of the built-in Rails helper distance_of_time_in_words. Basically, they were looking for a countdown that would dynamically let the customers know how much time they had left to order.
For those unfamiliar with distance_of_time_in_words, you provide it with Date & Time objects and it will state the duration between them in a more human readable format. For instance:
index.html.erb (View)
1 2 3 4 |
<%= distance_of_time_in_words( Time.now, 45.days.from_now ) %> # => about 1 month <%= distance_of_time_in_words( Time.mktime( 2008, 02, 05 ), Time.mktime( 2008, 03, 29 ) ) %> # => about 1 month |
This default behavior is great for informal purposes, such as how long it’s been since a blog article was posted or a comment made. However, I’ve come up with something a little more accurate:
1 2 3 4 |
<%= distance_of_time_in_words( Time.now, 45.days.from_now ) %> # => 1 month, 14 days <%= distance_of_time_in_words( Time.mktime( 2008, 02, 05 ), Time.mktime( 2008, 03, 29 ) ) %> # => 1 month, 22 days |
application_helper.rb (Helper)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
def distance_of_time_in_words( from_time, to_time = 0, include_seconds = true ) from_time = from_time.to_time if from_time.respond_to?(:to_time) to_time = to_time.to_time if to_time.respond_to?(:to_time) distance_in_minutes = (((to_time - from_time).abs)/60).round distance_in_seconds = ((to_time - from_time).abs).round case distance_in_minutes when 0..1 case distance_in_seconds when 0..59 then "#{pluralize( distance_in_seconds, 'second' )}" else "1 minute" end when 2..59 then "#{distance_in_minutes} minutes" when 60 then "1 hour" when 61..1439 then hours, minutes = (distance_in_minutes.to_f / 60.0), (distance_in_minutes.to_f % 60.0) "#{pluralize( hours.floor, 'hour' )}, #{pluralize( minutes.floor, 'minutes' )}" when 1440..1500 then "1 day" when 1501..2879 then "1 day, #{pluralize( (distance_in_minutes.to_f / 60 - 24).floor, 'hour' )}" when 2880..43199 then "#{(distance_in_minutes / 1440).round} days" when 43200..44641 then "1 month" when 44641..86399 then "1 month, #{pluralize( ( distance_in_minutes / 1440 - 30 ).floor, 'day' )}" when 86400..525599 then "over #{(distance_in_minutes / 43200).floor} months" else "over #{pluralize( (distance_in_minutes / 525600).round, 'years' ) }" end end |
1 2 |
<%= time_ago_in_words( Time.mktime( 2008, 03, 29 ) ) %> #=> 1 month, 22 days (assuming current time is February 5th, 2008) |

Sorry, comments are closed for this article.