Rails에서 상대 시간은 어떻게합니까?


220

Rails 애플리케이션을 작성하고 있지만 상대 시간을 수행하는 방법을 찾지 못하는 것 같습니다. 예를 들어 특정 Time 클래스가 지정된 경우 "30 초 전"또는 "2 일 전"또는 1 개월 이상인 경우 계산할 수 있습니다 "2008 년 9 월 1 일"등


1
'계산'이 잘못된 단어 인 것 같습니다. '출력'을 의미 했습니까?
lulalala

답변:


366

ActiveSupport에서 time_ago_in_words메소드 (또는 distance_of_time_in_words)를 찾고있는 것처럼 들립니다. 다음과 같이 호출하십시오.

<%= time_ago_in_words(timestamp) %>

4
irb에서 이것을 실행하는 방법에 대한 루비 초보자를위한 힌트? 나는 'active_support'를 필요로하고 'time_ago_in_words (Time.now)'를 시도하지만 함수를 찾을 수 없습니다.
cboettig

2
@cboettig의 일부가 아니며에 ActiveSupport정의되어 ActionView::Helpers::DateHelper있습니다.
Michael Kohl

19
Rails 콘솔에있는 경우 'active_support'가 필요하지 않습니다. helper이러한 메소드를 호출하고 액세스 할 수 있는 콘솔 메소드 가 있습니다. helper.time_ago_in_words(timestamp)
Matt Polito

2
참고로, irb 또는 일반 Ruby에서 이것을 원한다면, require 'active_support/core_ext' 먼저 : 다음을 사용하십시오 7.days.ago.
likethesky

1
큰! 나는 단지 약간의 샘플 코드를 기대하고 여기에 왔고 이것을 발견했다. 나는 루비와 레일을 좋아한다
Marcelo Biffara

53

나는 이것을 작성했지만 더 나은지 확인하기 위해 언급 된 기존 방법을 확인해야합니다.

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
흠, 나는 첫 번째 루비를 읽었고 루비는 기본적으로 ActiveSupport를 가지고 있지 않습니다. 그래서 나는이 게시물이 더 루비라고 생각합니다. 그러나 실제 질문에는 레일에 대한 언급이 있습니다.
Jonke

Rails는 웹 프레임 워크이며 기본 언어는 루비입니다. 따라서 레일즈 질문에 루비 코드를 얻는 것이 일반적입니다. 표준 루비에 ActiveRecord가 포함되어 있지 않더라도 "gem install activerecord"명령만으로 지원됩니다.
MickaelFM

7
아래 returncase명령문 내에 마지막 행을 넣고 else모든 returns를 제거 할 수 있습니다 .
sawa

2
누군가 왜 그런지 알 수 +99 +800 +180000있습니까?
Gaurav Shah

"1 시간 전"의 끝이 7100에서 끝나기 때문에 +99입니다.이 시간은 100 초입니다. 마찬가지로 172000이 이틀 (172800 초)보다 800 초 짧기 때문에 +800 등입니다.
Fred

22

time_ago_in_words
(Rails 3.0 및 Rails 4.0) 를 사용하기위한 Andrew Marshall의 솔루션을 명확히하기 위해

당신이 볼 수 있다면

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

당신이 컨트롤러에있는 경우

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

컨트롤러에는 ActionView :: Helpers :: DateHelper 모듈 을 기본적으로 가져 오지 않습니다 .

NB 헬퍼를 컨트롤러로 가져 오는 것은 "레일 방식"이 아닙니다. 도우미는 뷰를 돕는 데 도움이됩니다. time_ago_in_words의 방법은 것으로 결정되었다 엔터티 MVC의 화음. (나는 동의하지 않지만 로마에있을 때 ...)


20

이건 어떤가요

30.seconds.ago
2.days.ago

아니면 당신이 촬영 한 다른 것이 있습니까?


19
이것은 질문이 말하는 것과 거꾸로 있습니다.
xaxxon

12

산술 연산자를 사용하여 상대 시간을 수행 할 수 있습니다.

Time.now - 2.days 

2 일 전에 드리겠습니다.


10
2.days.ago에 대해 알고 있습니까?
webmat

2
`Time.now + 2.days '에 대한 속기 방법이 있습니까?
Stefan

23
@NixNinja : 2.days.since또는2.days.from_now
Brian Donovan

5
이것은 질문이 요구 한 것에서 거꾸로 나온 것입니다. time_ago_in_words는 질문에 대한 답변입니다.
xaxxon

정말 감사합니다.
Jigar Bhatt

10

이런 식으로 작동합니다.

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
이것은 본질적으로 distance_of_time_in_words 도우미의 재 구현입니다 : api.rubyonrails.com/classes/ActionView/Helpers/...
그랜트 허친스

2
당신은 그것을 사용하지 말아야 당신은 내장 사용해야하는 수단
xaxxon

이것은 나에게 완벽하게 보인다. 나머지 문자열을 사용자 정의 할 수 있습니다. 예 : "3 초 전"vs "3s 전"
raidfive

#{diff_seconds/360}이어야합니다 #{diff_seconds/3600}. 편집했습니다.
Femaref

7

여기에 가장 답변이 많으므로 time_ago_in_words가 제안 됩니다 .

사용하는 대신 :

<%= time_ago_in_words(comment.created_at) %>

Rails에서 선호하는 사항 :

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

코드와 함께 jQuery 라이브러리 http://timeago.yarp.com/ 과 함께 :

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

주요 장점 : 캐싱

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


1
실제로, 그것은 time_ago_in_words시간 이 아니다 S
23tux

6

여기에서 인스턴스 메소드를 살펴보십시오.

http://apidock.com/rails/Time

여기에는 어제, 내일, 시작 _ 주, 전 등과 같은 유용한 방법이 있습니다.

예 :

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

1

Rails ActiveRecord 객체를 위해 보석을 작성했습니다. 이 예제에서는 created_at을 사용하지만 updated_at 또는 ActiveSupport :: TimeWithZone 클래스의 모든 항목에서도 작동합니다.

보석을 설치하고 TimeWithZone 인스턴스에서 'pretty'메소드를 호출하십시오.

https://github.com/brettshollenberger/hublot


1

Rails 애플리케이션을 구축하는 경우

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

이를 통해 Rails 애플리케이션을 구성한 시간대의 시간 또는 날짜가 제공됩니다.

예를 들어, UTC를 사용하도록 응용 프로그램을 구성 Time.zone.now하면 항상 UTC 시간이됩니다 (예를 들어 영국 서머 타임 변경에 영향을받지 않음).

상대 시간 계산이 쉽습니다. 예 :

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.