Caching time_ago_in_words

June 2nd, 2007

I’m a big fan of the “english” timestamps that so often get used in apps these days; “Sat Jun 02 17:55:56 -0700 2007″ means almost nothing to me without active thought. It is much nicer to read “about a minute ago”, it requires no processing on my part. As many of you know, rails bundles this functionality into a helper called time_ago_in_words, and it works wonderfully.

The only issue is that you can’t page cache these timestamps. If you do, “one minute ago” won’t be right in short order. So, I worked up a little remix for time_ago_in_words that solves this problem.

The secret sauce is Javascript, as usual. cacheable_time_ago_in_words outputs a javascript call that does the translation:

  module CachedDateHelper
    def cachable_time_ago_in_words(from)
      js_call = javascript_tag "document.write(time_ago_in_words(#{(from.to_i * 1000).to_json}) + ' ago');"
      <<-EOS
        #{js_call}
        
      EOS
    end
  end

And then, on the javascript side:

  function time_ago_in_words(from) {
   return distance_of_time_in_words(new Date().getTime(), from) 
  }

  function distance_of_time_in_words(to, from) {
    seconds_ago = ((to  - from) / 1000);
    minutes_ago = Math.floor(seconds_ago / 60)

    if(minutes_ago == 0) { return "less than a minute";}
    if(minutes_ago == 1) { return "a minute";}
    if(minutes_ago < 45) { return minutes_ago + " minutes";}
    if(minutes_ago < 90) { return " about 1 hour";}
    hours_ago  = Math.round(minutes_ago / 60);
    if(minutes_ago < 1440) { return "about " + hours_ago + " hours";}
    if(minutes_ago < 2880) { return "1 day";}
    days_ago  = Math.round(minutes_ago / 1440);
    if(minutes_ago < 43200) { return days_ago + " days";}
    if(minutes_ago < 86400) { return "about 1 month";}
    months_ago  = Math.round(minutes_ago / 43200);
    if(minutes_ago < 525960) { return months_ago + " months";}
    if(minutes_ago < 1051920) { return "about 1 year";}
    years_ago  = Math.round(minutes_ago / 525960);
    return "over " + years_ago + " years" 
  }

You’ll notice there is no support for the rails-like include_seconds option. That is left as an exercise for the reader (ie. I don’t need to use it). Using this helper will let you page cache your views, greatly improving performance. It even has a fallback to absolute timestamps for those out there with a javascript disability.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • DZone
  • Digg
  • Reddit
  • del.icio.us
  • Blue Dot
  • StumbleUpon
  • Netscape
  • Ma.gnolia
  • Slashdot
  • Technorati
  • NewsVine
  • Netvouz

2 Responses to “Caching time_ago_in_words”

  1. Juergen Says:

    Great job, works great for me! Does one need to worry about timezones at all?

  2. nullstyle Says:

    The version posted in this article fails for timezone considerations.

    But, the latest version (http://nullstyle.com/wp-content/uploads/2007/11/jsdates.txt) plays nice with timezones.

Leave a Reply