Rails'te göreli zamanı nasıl yapıyorsunuz?


220

Bir Rails uygulaması yazıyorum, ancak göreceli zamanın nasıl yapılacağını bulamıyorum, yani belirli bir Time sınıfı verilirse, "30 saniye önce" veya "2 gün önce" hesaplayabilir veya bir aydan uzunsa "9/1/2008" vb.


1
'hesapla' yanlış kelime gibi görünüyor, 'çıktı' mı demek istediniz?
lulalala

Yanıtlar:


366

Senin gibi Sesler aradığınız time_ago_in_wordsyöntemi (veya distance_of_time_in_wordsActiveSupport gelen). Buna şöyle deyin:

<%= time_ago_in_words(timestamp) %>

4
Bunu irb'de nasıl çalıştırabileceğiniz yakut bir acemi için ipuçları? Çalıştırıyorum: 'active_support' gerektirir ve sonra 'time_ago_in_words (Time.now)' deneyin ama işlev bulunamadı.
cboettig

2
@cboettig Bir parçası değil ActiveSupport, içinde tanımlandı ActionView::Helpers::DateHelper.
Michael Kohl

19
raylar konsolundaysanız 'active_support' gerekmez. helperbu yöntemleri arayabileceğiniz ve erişebileceğiniz bir konsol yöntemi vardır . helper.time_ago_in_words(timestamp)
Matt Polito

2
Sadece fyi, bunu irb'de veya düz Ruby'de istiyorsanız, sadece bir tane yapın: require 'active_support/core_ext' İlk olarak, sonra hepiniz kullanmaya 7.days.agove diğer benzer yapılara hazırsınız .
likethesky

1
harika! Ben sadece buraya bazı örnek kod beklemek geldi ve buldum. Ruby ve raylar seviyorum
Marcelo Biffara

53

Bunu yazdım, ancak daha iyi olup olmadıklarını görmek için belirtilen mevcut yöntemleri kontrol etmeliyim.

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, ilk ruby ​​okudum ve ruby'nin kutudan ActiveSupport'u yok. Bence bu yazı daha yakut. Ancak asıl soruda raylardan bahsediliyor.
Jonke

Rails bir web çerçevesidir ve temel dil yakuttur. Bu yüzden bir ray sorusu üzerine yakut kodu almak normaldir. Standart ruby ​​ActiveRecord içermese bile, sadece bir "gem install activerecord" komutuyla desteklenir.
MickaelFM

7
Son returnsatırı aşağıdaki caseifadenin içine yerleştirebilir elseve tümünü kaldırabilirsiniz return.
sawa

2
birisi neden olduğunu söyleyebilir +99 +800 +180000mi?
Gaurav Shah

+99 çünkü "bir saat önce" nin sonu iki saatin 100 saniye kısa olan 7100'de biter. Benzer şekilde, +800, 172000'den beri iki gün (172800 saniye) 800 saniye kısadır ve bu böyle devam eder.
Fred

22

Andrew Marshall'ın time_ago_in_words kullanma çözümünü açıklığa kavuşturmak için
(Rails 3.0 ve Rails 4.0 için)

Bir görünümdeyseniz

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

Bir denetleyicide iseniz

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

Denetleyiciler varsayılan olarak ActionView :: Helpers :: DateHelper modülünü içe aktarmaz .

Not Denetleyicilerinize yardımcıları almak "raylar yolu" değildir. Yardımcılar, görüşlere yardımcı olmak içindir. Time_ago_in_words yöntem olmaya karar verildi görünüm içinde varlık MVC üçlü. (Katılmıyorum ama Roma'dayken ...)


20

Ne dersin

30.seconds.ago
2.days.ago

Ya da çektiğiniz başka bir şey mi?


19
bu sorunun ne ifade ettiğinden geriye dönüktür.
xaxxon

12

Göreceli zaman yapmak için aritmetik işleçleri kullanabilirsiniz.

Time.now - 2.days 

2 gün önce vereceğim.


10
2.days.ago hakkında bilginiz var mı?
webmat

2
`` Time.now + 2.days '' için kestirme yöntem var mı?
Stefan

23
@NixNinja: 2.days.sinceveya2.days.from_now
Brian Donovan

5
bu sorunun sorduğundan geriye dönüktür. time_ago_in_words sorunun cevabıdır.
xaxxon

Çok teşekkür ederim.
Jigar Bhatt

10

Böyle bir şey işe yarayacaktır.

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
Bu aslında distance_of_time_in_words yardımcısının bir yeniden uygulamasıdır: api.rubyonrails.com/classes/ActionView/Helpers/…
Grant Hutchins

2
Bu, onu kullanmamanız ve yerleşik olarak kullanmanız gerektiği anlamına gelir
xaxxon

Bu benim için gayet iyi görünüyor. Dizelerin geri kalanını özelleştirmenizi sağlar. ie "3 saniye önce" vs "3s önce"
raidfive

#{diff_seconds/360}olmalı #{diff_seconds/3600}. Ben düzenledim.
Femaref

7

Burada en çok yanıt time_ago_in_words önerdiğinden beri .

Kullanmak yerine :

<%= time_ago_in_words(comment.created_at) %>

Rails'te:

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

http://timeago.yarp.com/ adresinde bir jQuery kütüphanesiyle birlikte:

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

Ana avantajı: önbellekleme

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


1
aslında, time_ago_in_wordssaat S
23tux

6

Buradaki örnek yöntemlere bir göz atın:

http://apidock.com/rails/Time

Bunun dün, yarın, başlangıç_haftası, önce vb. Gibi yararlı yöntemleri vardır.

Örnekler:

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

1

Rails ActiveRecord nesneleri için bunu yapan bir mücevher yazdım. Örnek oluşturulmuş_at kullanır, ancak updated_at veya ActiveSupport :: TimeWithZone sınıfındaki herhangi bir şey üzerinde de çalışır.

Sadece gem yükleyin ve TimeWithZone örneğinizde 'güzel' yöntemini çağırın.

https://github.com/brettshollenberger/hublot


1

Bir Rails uygulaması oluşturuyorsanız,

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

Bu, Rails uygulamanızı yapılandırdığınız saat diliminde saat veya tarih verir.

Örneğin, uygulamanızı UTC kullanacak şekilde yapılandırırsanız Time.zone.now, her zaman UTC saatinde olur (örneğin İngiliz Yaz Saati değişikliğinden etkilenmez).

Göreli süreyi hesaplamak kolaydır, ör.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.