2008-10-12 18 views
216

Estoy escribiendo una aplicación de Rails, pero parece que no puedo encontrar cómo hacer la hora relativa, es decir, si se le da una determinada clase de tiempo, puede calcular "30 segundos atrás" o "hace 2 días" o si es más larga que un mes "9/1/2008", etc.¿Cómo se hace el tiempo relativo en Rails?

+1

'Calcular' parece ser la palabra equivocada, quiso decir 'salida'? – lulalala

Respuesta

12

Puede usar los operadores aritméticos para hacer el tiempo relativo.

Time.now - 2.days 

Te regalaré hace 2 días.

+10

¿Sabías de 2.days.ago? – webmat

+2

hay un método abreviado para 'Time.now + 2.days '? – Stefan

+23

@NixNinja: '2.days.since' o' 2.days.from_now' –

7

Algo como esto funcionaría.

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 
+11

Esto es esencialmente una reimplementación del ayudante de distance_of_time_in_words: http://api.rubyonrails.com/classes/ActionView/Helpers/DateHelper.html#M001712 – nertzy

+1

sí y sí;) –

+2

lo que significa que no debe usarlo y debe usar el – xaxxon

19

¿Qué hay de

30.seconds.ago 
2.days.ago 

O algo más que estaban disparando a?

+19

esto está al revés de lo que dice la pregunta. – xaxxon

354

Parece que está buscando el método time_ago_in_words (o distance_of_time_in_words), de ActiveSupport. Llámalo así:

<%= time_ago_in_words(timestamp) %> 
+4

Consejos para un novato de ruby ​​sobre cómo ejecutar esto en irb? Ejecuto: requieren 'active_support' y luego prueban 'time_ago_in_words (Time.now)' pero la función no se encuentra. – cboettig

+2

@cboettig No es parte de 'ActiveSupport', se define en' ActionView :: Helpers :: DateHelper'. –

+19

no necesita requerir 'active_support' si se encuentra en una consola de rieles. hay un método de consola llamado 'helper' al que puede llamar y acceder a estos métodos. 'helper.time_ago_in_words (fecha y hora)' –

51

He escrito esto, pero tengo que verificar los métodos existentes mencionados para ver si son mejores.

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 
+1

Hum, leo primero ruby, y ruby ​​no tengo ActiveSupport listo para usar. Así que creo que esta publicación es más ruby. Sin embargo, en la pregunta real hay una mención de los rieles. – Jonke

+0

Rails es un framework web y el lenguaje subyacente es ruby. Por lo tanto, es normal obtener un código de rubí en una pregunta sobre raíles. Incluso si ruby ​​estándar no incluye ActiveRecord, es compatible con solo un comando "gem install activerecord". – MickaelFM

+7

Puede colocar la última línea de 'return' dentro de la sentencia 'case' bajo' else', y eliminar todos los 'return's. – sawa

5

Tome un vistazo a los métodos de instancia aquí:

http://apidock.com/rails/Time

Esto tiene métodos útiles como ayer, mañana, beginning_of_week, hace, etc.

Ejemplos:

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

He escrito una joya que hace esto para Rails Acti objetos VeRecord. El ejemplo usa created_at, pero también funcionará en updated_at o cualquier cosa con la clase ActiveSupport :: TimeWithZone.

Simplemente joda, instala y llama al método 'bonito' en tu instancia de TimeWithZone.

20

Solo para aclarar la solución de Andrew Marshall para el uso de time_ago_in_words
(Para Rails 3.0 y Rails 4.0)

Si se encuentra en una vista

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

Si está en un controlador

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

Los controladores no tienen el módulo ActionView::Helpers::DateHelper importado por defecto.

N. B. No es "la manera de los rieles" para importar ayudantes en sus controladores. Los ayudantes son para ayudar a las vistas. Se decidió time_ago_in_words método para ser una entidad de vista en la tríada MVC. (No estoy de acuerdo, pero cuando en Roma ...)

6

Dado que la mayoría de las respuestas aquí sugiere time_ago_in_words.

En lugar de utilizar:

<%= times_ago_in_words(comment.created_at) %> 

En Rails, Prefiero:

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

alongwith una biblioteca jQuery http://timeago.yarp.com/, con el código:

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

principal ventaja: El almacenamiento en caché

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

+0

en realidad, es 'time_ago_in_words' no el tiempo ** S ** – 23tux

0

Otro enfoque es para descargar algo de lógica desde el servidor y el navegador maek hacer el trabajo mediante el uso de plugins de Javascript tales como:

jQuery time ago o su Rails Gem adaptation

0

Si usted está construyendo una aplicación Rails , se debe utilizar

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

Esto le da tiempo o la fecha en la zona horaria con la que se ha configurado su aplicación Rails.

Por ejemplo, si configura su aplicación para usar UTC, entonces Time.zone.now siempre estará en hora UTC (no se verá afectado por el cambio de horario de verano británico, por ejemplo).

calcular el tiempo relativo es fácil, por ejemplo

Time.zone.now - 10.minute 
Time.zone.today.days_ago(5) 
Cuestiones relacionadas