Rails에서 한 시간대에서 다른 시간대로 시간 변환


105

created_at타임 스탬프는 UTC로 저장됩니다.

>> Annotation.last.created_at
=> Sat, 29 Aug 2009 23:30:09 UTC +00:00

그중 하나를 '동부 표준시 (미국 및 캐나다)'로 변환하려면 어떻게해야합니까 (일광 절약 제 고려)? 다음과 같은 것 :

Annotation.last.created_at.in_eastern_time

답변:


191

DateTime 클래스의 in_time_zone 메서드 사용

Loading development environment (Rails 2.3.2)
>> now = DateTime.now.utc
=> Sun, 06 Sep 2009 22:27:45 +0000
>> now.in_time_zone('Eastern Time (US & Canada)')
=> Sun, 06 Sep 2009 18:27:45 EDT -04:00
>> quit

따라서 귀하의 특정 예를 들어

Annotation.last.created_at.in_time_zone('Eastern Time (US & Canada)')

7
아니면 그냥 시간 ident를 사용할 수 있습니다now.in_time_zone(3)
fl00r 2011 년

8
created_at.in_time_zone("EST")더 짧습니다
올랜도

51
"EST"= "동부 표준시"이므로 일광 절약 시간 중에는 잘못된 것입니다. "동부 표준시 (미국 및 캐나다)"는 DST인지 여부를 알려줍니다.
jhiro009

1
in_time_zone 메소드는 ActiveSupport의 일부이므로 Rails에 내장되어 있지만 Ruby stdlib의 일부는 아닙니다. Rails 앱이 있어도 문제 없습니다. 스트레이트 루비 앱이 있다면 적극적인 지원이 필요합니다.
Gayle 2013 년

이 방법에 대한 문서 링크 : apidock.com/rails/DateTime/in_time_zone
Naved Khan

17

이것은 오래된 질문이지만 언급 할 가치가 있습니다. A의 이전 응답 이 일시적으로 시간대를 설정하는 before_filter를 사용하도록 제안합니다.

Time.zone이 정보를 스레드에 저장하고 해당 스레드가 처리하는 다음 요청으로 누출 될 수 있으므로 절대 그렇게 해서는 안됩니다 .

대신 around_filter를 사용하여 요청이 완료된 후 Time.zone이 재설정되었는지 확인해야합니다. 다음과 같은 것 :

around_filter :set_time_zone

private

def set_time_zone
  old_time_zone = Time.zone
  Time.zone = current_user.time_zone if logged_in?
  yield
ensure
  Time.zone = old_time_zone
end

여기 에 대해 자세히 알아보십시오.


1
요즘에는 좋은 Time.use_zone 메소드가 있습니다.
freemanoid

9

이것을 추가하면 /config/application.rb

config.time_zone = 'Eastern Time (US & Canada)'

그런 다음 세포를

Annotation.last.created_at.in_time_zone

지정된 시간대의 시간을 가져옵니다.


application.rb에서 시간대를 구성하는 경우 ".in_time_zone"을 호출 할 필요가 없습니다. 자동 Annotation.last.created_at 전화 우리 jyst 필요성을 위해 그것을 할 레일
이씨

3

구성하는 경우 /config/application.rb

config.time_zone = 'Eastern Time (US & Canada)'

Time.now.in_time_zone

DateTime.now.in_time_zone

2

시간대를 동부 표준시로 설정하십시오.

config / environment.rb에서 기본 시간대를 설정할 수 있습니다.

config.time_zone = "Eastern Time (US & Canada)"

이제 꺼내는 모든 레코드가 해당 시간대에 있습니다. 다른 시간대가 필요한 경우 사용자 시간대에 따라 컨트롤러의 before_filter를 사용하여 변경할 수 있습니다.

class ApplicationController < ActionController::Base

  before_filter :set_timezone

  def set_timezone
    Time.zone = current_user.time_zone
  end
end

모든 시간을 데이터베이스에 UTC로 저장하고 있는지 확인하면 모든 것이 멋질 것입니다.


잡종, 씬 또는 승객과 같은 애플리케이션 서버를 실행하는 경우 이것이 중요합니까? 그들은 하나 이상의 인스턴스를 실행하고 단일 스레드라고 생각합니까? 내가 틀렸을 수도 있고 알고 싶어요!
nitecoder 2010

4
Time.zone=스레드로부터 안전한 github.com/rails/rails/blob/master/activesupport/lib/… 입니다.
않을까

그것은 '09에 없었을 수도 있습니다.
nitecoder

2
@jpwynn : 이에 따르면 : github.com/rails/rails/commit/… 5 년 이상 스레드로부터 안전합니다. 문제에 대한 소스 또는 예가 있습니까?
Pascal

1
스레드는 여러 세션을 제공 할 수 있습니다. 사용자가 로그인 할 때 한 번 설정합니다. 예를 들어 로그인 한 마지막 사용자가 동일한 스레드를 사용하는 세션의 모든 사용자에 대한 시간대를 설정합니다. 따라서 모든 페이지로드에 대해 모든 사용자에 대해 설정하려면 before_filter를 사용해야합니다.
jpw 2013 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.