2009-10-15 7 views

Répondre

11

Si vous êtes sur des rails:

time_ago_in_words 
+3

Référence de l'API: http://api.rubyonrails.org/classes/ActionView/Helpers/ DateHelper.html # M001696 –

+2

Et le code source de la méthode en question, au cas où vous ne seriez pas sur Rails: http://dev.rubyonrails.org/browser/trunk/actionpack/lib/action_view/helpers/ date_helper.rb? rev = 4674 # L24 –

0

Vous devez faire quelque chose comme ceci:

tnow = Time.now 
elapsed = tnow - tevent # elapsed time in seconds 

if (elapsed < 60) 
    puts "#{elapsed} seconds ago" 
elsif (elapsed < 60*60) 
    puts "#{elapsed/60} minutes ago" 
end 
+1

Wow, Je n'ai pas réalisé que Ruby était si intelligent qu'il pouvait dire que * écoulé * et * épongé * se référait à la même variable :-) – paxdiablo

+2

@Pax: pourquoi ne pas éditer les (deux) fautes de frappe évidentes? – Telemachus

+0

Je modifie rarement les messages des autres quand ils sont nouveaux, je suppose que je m'attends à ce qu'ils les surveillent et les réparent. Si c'est resté comme ça pendant quelques jours, je pourrais le faire. Un cas d'espèce était une réponse récente qui utilisait l'expression «gank it off the website» - je pensais que c'était censé être «yank» mais non, apparemment c'est un mot (quoique probablement argot). OP serait probablement énervé si je l'avais changé. – paxdiablo

12

est ici la langue la version agnostique que vous devriez être en mesure de convertir en toute langue:

ONE_MINUTE = 60 
ONE_HOUR = 60 * ONE_MINUTE 
ONE_DAY = 24 * ONE_HOUR 
ONE_WEEK = 7 * ONE_DAY 
ONE_MONTH = ONE_DAY * 3652425/120000 
ONE_YEAR = ONE_DAY * 3652425/10000 

def when(then): 
    seconds_ago = now() - then 

    if seconds_ago < 0: 
     return "at some point in the future (???)" 
    if seconds_ago == 0: 
     return "now" 

    if seconds_ago == 1: 
     return "1 second ago" 
    if seconds_ago < ONE_MINUTE: 
     return str(seconds_ago) + " seconds ago" 

    if seconds_ago < 2 * ONE_MINUTE: 
     return "1 minute ago" 
    if seconds_ago < ONE_HOUR: 
     return str(seconds_ago/ONE_MINUTE) + " minutes ago" 

    if seconds_ago < 2 * ONE_HOUR: 
     return "1 hour ago" 
    if seconds_ago < ONE_DAY: 
     return str(seconds_ago/ONE_HOUR) + " hours ago" 

    if seconds_ago < 2 * ONE_DAY: 
     return "1 day ago" 
    if seconds_ago < ONE_WEEK: 
     return str(seconds_ago/ONE_DAY) + " days ago" 

    if seconds_ago < 2 * ONE_WEEK: 
     return "1 week ago" 
    if seconds_ago < ONE_MONTH: 
     return str(seconds_ago/ONE_WEEK) + " weeks ago" 

    if seconds_ago < 2 * ONE_MONTH: 
     return "1 month ago" 
    if seconds_ago < ONE_YEAR: 
     return str(seconds_ago/ONE_MONTH) + " months ago" 

    if seconds_ago < 2 * ONE_YEAR: 
     return "1 year ago" 
    return str(seconds_ago/ONE_YEAR) + " years ago" 

Notez que les chiffres de l'année/mois sont approximatif (basé sur des moyennes) mais cela ne devrait pas vraiment importer puisque l'erreur relative sera toujours très bas.

0

Voici un exemple complet si vous choisissez d'aller à l'extérieur de plein Rails, mais sont prêts à utiliser active_support (gem install actionview)

#!/usr/bin/env ruby 

require 'active_support' 
require 'active_support/core_ext/object/acts_like' 
require 'active_support/core_ext/time/acts_like' 
require 'action_view' 

require 'date' 

# Avoid a deprecation warning 
I18n.enforce_available_locales = false 

# Add time_ago_in_words 
extend ActionView::Helpers::DateHelper 

[ 
    '2014-04-24 16:20:00', 
    '2014-04-21 16:20:00', 
    '2014-03-24 16:20:00', 
    '2013-04-20 16:20:00', 
].map {|t| DateTime.parse t}.each do |time| 
    puts time_ago_in_words time 
end 

Au moment de l'écriture, cette sortie:

about 6 hours 
3 days 
about 1 month 
about 1 year