web-dev-qa-db-fra.com

Comment faites-vous le temps relatif dans Rails?

J'écris une application Rails, mais je ne parviens pas à trouver le temps relatif, c'est-à-dire que si on lui donne une certaine classe Time, il peut calculer "il y a 30 secondes" ou "2 jours il y a "ou si c'est plus long qu'un mois" 01/09/2008 ", etc.

222
lol_wut

On dirait que vous cherchez le time_ago_in_words méthode (ou distance_of_time_in_words ), à partir de ActiveSupport. Appelez ça comme ça:

<%= time_ago_in_words(timestamp) %>
363
Ben Scofield

J'ai écrit ceci, mais je dois vérifier les méthodes existantes mentionnées pour voir si elles sont meilleures.

module PrettyDate
  def to_pretty
    a = (Time.now-self).to_i

    case a
      when 0 then 'just now'
      when 1 then 'a second ago'
      when 2..59 then a.to_s+' seconds ago' 
      when 60..119 then 'a minute ago' #120 = 2 minutes
      when 120..3540 then (a/60).to_i.to_s+' minutes ago'
      when 3541..7100 then 'an hour ago' # 3600 = 1 hour
      when 7101..82800 then ((a+99)/3600).to_i.to_s+' hours ago' 
      when 82801..172000 then 'a day ago' # 86400 = 1 day
      when 172001..518400 then ((a+800)/(60*60*24)).to_i.to_s+' days ago'
      when 518400..1036800 then 'a week ago'
      else ((a+180000)/(60*60*24*7)).to_i.to_s+' weeks ago'
    end
  end
end

Time.send :include, PrettyDate
51
MattW.

Juste pour clarifier la solution d'Andrew Marshall pour l'utilisation time_ago_in_words
(Pour Rails 3.0 et Rails 4.0)

Si vous êtes dans une vue

<%= time_ago_in_words(Date.today - 1) %>

Si vous êtes dans un contrôleur

include ActionView::Helpers::DateHelper
def index
  @sexy_date = time_ago_in_words(Date.today - 1)
end

Les contrôleurs n'ont pas le module ActionView :: Helpers :: DateHelper importé par défaut.

N.B. Ce n'est pas "le moyen Rails") d'importer des helpers dans vos contrôleurs. Les helpers servent à aider les vues. time_ago_in_words méthode a été décidé d'être un vue entité dans le MVC triade. (Je ne suis pas d'accord mais quand à Rome ...)

22
seo

Qu'en est-il de

30.seconds.ago
2.days.ago

Ou quelque chose d'autre pour lequel vous tiriez?

20
Honza

Vous pouvez utiliser les opérateurs arithmétiques pour calculer le temps relatif.

Time.now - 2.days 

Je vais vous donner il y a 2 jours.

12
TonyLa

Quelque chose comme ça marcherait.

def relative_time(start_time)
  diff_seconds = Time.now - start_time
  case diff_seconds
    when 0 .. 59
      puts "#{diff_seconds} seconds ago"
    when 60 .. (3600-1)
      puts "#{diff_seconds/60} minutes ago"
    when 3600 .. (3600*24-1)
      puts "#{diff_seconds/3600} hours ago"
    when (3600*24) .. (3600*24*30) 
      puts "#{diff_seconds/(3600*24)} days ago"
    else
      puts start_time.strftime("%m/%d/%Y")
  end
end
9
Gordon Wilson

Étant donné que la plupart des réponses suggèrent ici time_ago_in_words .

À la place d'utiliser :

<%= time_ago_in_words(comment.created_at) %>

Dans Rails, préférez:

<abbr class="timeago" title="<%= comment.created_at.getutc.iso8601 %>">
  <%= comment.created_at.to_s %>
</abbr>

avec une bibliothèque jQuery http://timeago.yarp.com/ , avec le code:

$("abbr.timeago").timeago();

Principal avantage: la mise en cache

http://Rails-bestpractices.com/posts/2012/02/10/not-use-time_ago_in_words/

7
Rahul garg

Jetez un coup d'œil aux méthodes d'instance ici:

http://apidock.com/Rails/Time

Cela a des méthodes utiles comme hier, demain, début_de_ semaine, il y a, etc.

Exemples:

Time.now.yesterday
Time.now.ago(2.days).end_of_day
Time.now.next_month.beginning_of_month
6
davogones

Si vous construisez une application Rails, vous devez utiliser

Time.zone.now
Time.zone.today
Time.zone.yesterday

Cela vous donne l'heure ou la date dans le fuseau horaire avec lequel vous avez configuré votre application Rails.

Par exemple, si vous configurez votre application pour utiliser l'UTC, alors Time.zone.now sera toujours en heure UTC (par exemple, le changement de l'heure d'été britannique n'aura aucune incidence sur celui-ci).

Calculer le temps relatif est facile, par exemple

Time.zone.now - 10.minute
Time.zone.today.days_ago(5)
1
Zack Xu

J'ai écrit une gemme qui fait cela pour Rails ActiveRecord. L'exemple utilise created_at, mais il fonctionnera également avec updated_at ou n'importe quoi avec la classe ActiveSupport :: TimeWithZone.

Juste installer et appeler la méthode 'pretty' sur votre instance TimeWithZone.

https://github.com/brettshollenberger/hublot

1
Brett Shollenberger

Une autre approche consiste à décharger une partie de la logique du backend et à laisser le navigateur faire le travail en utilisant des plugins Javascript tels que:

jQuery time ago ou ses adaptation de Rails Gem

0
The Whiz of Oz