[ruby-on-rails] Ruby / Rails-값을 변경하지 않고 시간의 시간대 변경

및 속성 foo이있는 데이터베이스에 기록 이 있습니다 .:start_time:timezone

:start_time– UTC에서 시간입니다 2001-01-01 14:20:00예를 들어. 은 :timezone문자열입니다 – America/New_York예를 들면.

값이 :start_time이지만 시간대가로 지정된 새 Time 개체를 만들고 싶습니다 :timezone. Rails가 영리하고 UTC에서 해당 시간대와 일치하도록 시간을 업데이트하기 때문에 를로드 한 :start_time다음으로 변환 하고 싶지 않습니다 :timezone.

현재

t = foo.start_time
=> 2000-01-01 14:20:00 UTC
t.zone
=> "UTC"
t.in_time_zone("America/New_York")
=> Sat, 01 Jan 2000 09:20:00 EST -05:00

대신보고 싶어

=> Sat, 01 Jan 2000 14:20:00 EST -05:00

즉. 나하고 싶어:

t
=> 2000-01-01 14:20:00 UTC
t.zone = "America/New_York"
=> "America/New_York"
t
=> 2000-01-01 14:20:00 EST



답변

라인을 따라 무언가를 원하는 것 같습니다.

ActiveSupport::TimeZone.new('America/New_York').local_to_utc(t)

이것은이 현지 시간 (영역 사용)을 utc로 변환하는 것을 말합니다. Time.zone설정 한 경우 물론 다음을 수행 할 수 있습니다.

Time.zone.local_to_utc(t)

이것은 t에 첨부 된 시간대를 사용하지 않습니다. 변환하려는 시간대의 현지 시간대라고 가정합니다.

여기서 경계해야 할 한 가지 중요한 경우는 DST 전환입니다. 지정한 현지 시간이 존재하지 않거나 모호 할 수 있습니다.


답변

나는 방금 같은 문제에 직면했고 여기에 내가 할 일이 있습니다.

t = t.asctime.in_time_zone("America/New_York")

다음은 asctime에 대한 문서입니다.


답변

Rails를 사용하는 경우 Eric Walsh의 답변에 따른 또 다른 방법이 있습니다.

def set_in_timezone(time, zone)
  Time.use_zone(zone) { time.to_datetime.change(offset: Time.zone.now.strftime("%z")) }
end


답변

시간을 변환 한 후 시간 오프셋을 추가해야합니다.

이를 수행하는 가장 쉬운 방법은 다음과 같습니다.

t = Foo.start_time.in_time_zone("America/New_York")
t -= t.utc_offset

왜 그렇게 하려는지 잘 모르겠지만 실제로 시간이 만들어지는 방식으로 작업하는 것이 가장 좋습니다. 시간과 시간대를 변경해야하는 이유에 대한 배경 지식이 도움이 될 것 같습니다.


답변

실제로 다음과 같이 변환 한 후에 오프셋을 빼야한다고 생각합니다.

1.9.3p194 :042 > utc_time = Time.now.utc
=> 2013-05-29 16:37:36 UTC
1.9.3p194 :043 > local_time = utc_time.in_time_zone('America/New_York')
 => Wed, 29 May 2013 12:37:36 EDT -04:00
1.9.3p194 :044 > desired_time = local_time-local_time.utc_offset
 => Wed, 29 May 2013 16:37:36 EDT -04:00 


답변

이번에 사용할 위치에 따라 다릅니다.

시간이 속성 일 때

시간이 속성으로 사용되는 경우 동일한 date_time_attribute gem을 사용할 수 있습니다 .

class Task
  include DateTimeAttribute
  date_time_attribute :due_at
end

task = Task.new
task.due_at_time_zone = 'Moscow'
task.due_at                      # => Mon, 03 Feb 2013 22:00:00 MSK +04:00
task.due_at_time_zone = 'London'
task.due_at                      # => Mon, 03 Feb 2013 22:00:00 GMT +00:00

별도의 변수를 설정하는 경우

동일한 date_time_attribute gem을 사용하십시오 .

my_date_time = DateTimeAttribute::Container.new(Time.zone.now)
my_date_time.date_time           # => 2001-02-03 22:00:00 KRAT +0700
my_date_time.time_zone = 'Moscow'
my_date_time.date_time           # => 2001-02-03 22:00:00 MSK +0400


답변

def relative_time_in_time_zone(time, zone)
   DateTime.parse(time.strftime("%d %b %Y %H:%M:%S #{time.in_time_zone(zone).formatted_offset}"))
end

일을 해결하기 위해 내가 생각 해낸 빠른 작은 기능. 누군가가 더 효율적인 방법을 가지고 있다면 그것을 게시하십시오!