복붙노트

[RUBY-ON-RAILS] 루비 / 레일 - 변경 값을 변경하지 않고 시간의 시간대,

RUBY-ON-RAILS

루비 / 레일 - 변경 값을 변경하지 않고 시간의 시간대,

START_TIME과 : 시간대 속성을 나는이 데이터베이스에 기록 foo에 있습니다.

: - 예를 들어, 2001-01-01 14시 20분 0초 START_TIME은 UTC에서 시간입니다. : - 미국 / 뉴욕, 예를 들어 시간대는 문자열입니다.

시간대에 의해 지정됩니다 START_TIME :하지만 시간대 나는의 값을 가진 새로운 시간 개체를 만들려고합니다. 그 시간대와 일치하는 UTC에서 시간을 시간대, 레일 영리 될 것입니다 때문에 업데이트 : START_TIME 다음으로 변환 : 나는를로드하지 않습니다.

현재,

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

해결법

  1. ==============================

    1.당신 같은 소리의 라인을 따라 뭔가를 원하는

    당신 같은 소리의 라인을 따라 뭔가를 원하는

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

    이 협정이 현지 시간 (영역 사용)로 변환했다. 당신이 다음 Time.zone 설정이있는 경우에 과정의 수 있습니다

    Time.zone.local_to_utc(t)
    

    이 t에 부착 된 시간대를 사용하지 않습니다 - 그것은 당신이에서 변환하는 시간대에 지역 있다고 가정합니다.

    여기 방지하려면 하나의 가장자리 경우 DST 전환이다 : 당신이 존재하지 않을 수 지정하거나 현지 시간은 모호 할 수 있습니다.

  2. ==============================

    2.난 그냥 같은 문제에 직면하고 여기에 내가 할거야 무엇했습니다 :

    난 그냥 같은 문제에 직면하고 여기에 내가 할거야 무엇했습니다 :

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

    여기 asctime과에 대한 설명서입니다

  3. ==============================

    3.당신이 레일을 사용하는 경우, 여기 에릭 월시의 대답의 라인을 따라 또 다른 방법은 다음과 같다 :

    당신이 레일을 사용하는 경우, 여기 에릭 월시의 대답의 라인을 따라 또 다른 방법은 다음과 같다 :

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

    4.당신은 당신이 그것을 변환 후 시간에 시간 오프셋을 추가해야합니다.

    당신은 당신이 그것을 변환 후 시간에 시간 오프셋을 추가해야합니다.

    이 작업을 수행하는 가장 쉬운 방법은 다음과 같습니다

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

    그것은 시간이 실제로 사업에 아마 그들이 구축하는 방법 최고의 비록 나는 확실히 당신은 왜, 이렇게 할 것 아니에요. 난 당신이 이동 시간을 필요로하고 시간대가 도움이 될 것입니다 이유에 대한 배경을 것 같아요.

  5. ==============================

    5.사실, 난 당신이 같이 변환 후 오프셋을 뺄 필요가 있다고 생각합니다 :

    사실, 난 당신이 같이 변환 후 오프셋을 뺄 필요가 있다고 생각합니다 :

    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 
    
  6. ==============================

    6.이 시간을 사용하려는 위치에 따라 달라집니다.

    이 시간을 사용하려는 위치에 따라 달라집니다.

    당신의 시간은 속성 인 경우

    시간이 속성으로 사용하는 경우, 동일한 date_time_attribute 보석을 사용할 수 있습니다 :

    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 보석을 사용합니다 :

    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
    
  7. ==============================

    7.

    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
    

    빠른 작은 기능 나는 일을 해결하기 위해 함께했다. 누군가가이 일을보다 효율적인 방법이 있다면 그것을 게시하시기 바랍니다!

  8. ==============================

    8.

    t.change(zone: 'America/New_York')
    

    영업 이익의 전제는 잘못된 것입니다 : "나는로드하고 싶지 않은 : START_TIME를 다음으로 변환 :. 레일은 영리하고 시간대와 일치하는 UTC에서 시간을 업데이트하기 때문에, 시간대" 여기에 제공된 답변에 의해 입증 된 바와 같이 이것은 반드시 사실이 아니다.

  9. ==============================

    9.값을 변경하지 않고, 변경 시간의 시간대 - 루비 / 레일에서 게시물의 원래 저자에 의해 요청대로 그냥 같은 일을 하나의 몇 가지 헬퍼 메소드를 만들었습니다.

    값을 변경하지 않고, 변경 시간의 시간대 - 루비 / 레일에서 게시물의 원래 저자에 의해 요청대로 그냥 같은 일을 하나의 몇 가지 헬퍼 메소드를 만들었습니다.

    또한 내가 몇 내가 관찰 특수성과 이러한 헬퍼를 문서화 완전히 자동으로 일 빛 절감 효과를 무시하는 방법을 포함하고 적용하는 동안 즉시 사용할 수 레일 프레임 워크에없는 시간 변환 :

      def utc_offset_of_given_time(time, ignore_dst: false)
        # Correcting the utc_offset below
        utc_offset = time.utc_offset
    
        if !!ignore_dst && time.dst?
          utc_offset_ignoring_dst = utc_offset - 3600 # 3600 seconds = 1 hour
          utc_offset = utc_offset_ignoring_dst
        end
    
        utc_offset
      end
    
      def utc_offset_of_given_time_ignoring_dst(time)
        utc_offset_of_given_time(time, ignore_dst: true)
      end
    
      def change_offset_in_given_time_to_given_utc_offset(time, utc_offset)
        formatted_utc_offset = ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, false)
    
        # change method accepts :offset option only on DateTime instances.
        # and also offset option works only when given formatted utc_offset
        # like -0500. If giving it number of seconds like -18000 it is not
        # taken into account. This is not mentioned clearly in the documentation
        # , though.
        # Hence the conversion to DateTime instance first using to_datetime.
        datetime_with_changed_offset = time.to_datetime.change(offset: formatted_utc_offset)
    
        Time.parse(datetime_with_changed_offset.to_s)
      end
    
      def ignore_dst_in_given_time(time)
        return time unless time.dst?
    
        utc_offset = time.utc_offset
    
        if utc_offset < 0
          dst_ignored_time = time - 1.hour
        elsif utc_offset > 0
          dst_ignored_time = time + 1.hour
        end
    
        utc_offset_ignoring_dst = utc_offset_of_given_time_ignoring_dst(time)
    
        dst_ignored_time_with_corrected_offset =
          change_offset_in_given_time_to_given_utc_offset(dst_ignored_time, utc_offset_ignoring_dst)
    
        # A special case for time in timezones observing DST and which are
        # ahead of UTC. For e.g. Tehran city whose timezone is Iran Standard Time
        # and which observes DST and which is UTC +03:30. But when DST is active
        # it becomes UTC +04:30. Thus when a IRDT (Iran Daylight Saving Time)
        # is given to this method say '05-04-2016 4:00pm' then this will convert
        # it to '05-04-2016 5:00pm' and update its offset to +0330 which is incorrect.
        # The updated UTC offset is correct but the hour should retain as 4.
        if utc_offset > 0
          dst_ignored_time_with_corrected_offset -= 1.hour
        end
    
        dst_ignored_time_with_corrected_offset
      end
    

    레일 본체 또는 클래스 또는 모듈에서 상기 방법 배치 후 루비 스크립트를 시도 할 수있다 예 :

    dd1 = '05-04-2016 4:00pm'
    dd2 = '07-11-2016 4:00pm'
    
    utc_zone = ActiveSupport::TimeZone['UTC']
    est_zone = ActiveSupport::TimeZone['Eastern Time (US & Canada)']
    tehran_zone = ActiveSupport::TimeZone['Tehran']
    
    utc_dd1 = utc_zone.parse(dd1)
    est_dd1 = est_zone.parse(dd1)
    tehran_dd1 = tehran_zone.parse(dd1)
    
    utc_dd1.dst?
    est_dd1.dst?
    tehran_dd1.dst?
    
    ignore_dst = true
    utc_to_est_time = utc_dd1.in_time_zone(est_zone.name)
    if utc_to_est_time.dst? && !!ignore_dst
      utc_to_est_time = ignore_dst_in_given_time(utc_to_est_time)
    end
    
    puts utc_to_est_time
    

    도움이 되었기를 바랍니다.

  10. ==============================

    10.나뿐만 아니라에서 시간대 어려움을 겪고 상당한 시간을 소비하고, 루비 1.9.3 땜질 후 변환하기 전에 이름이 지정된 시간대 심볼로 변환 할 필요가 없습니다 것을 깨달았다 :

    나뿐만 아니라에서 시간대 어려움을 겪고 상당한 시간을 소비하고, 루비 1.9.3 땜질 후 변환하기 전에 이름이 지정된 시간대 심볼로 변환 할 필요가 없습니다 것을 깨달았다 :

    my_time = Time.now
    west_coast_time = my_time.in_time_zone(-8) # Pacific Standard Time
    east_coast_time = my_time.in_time_zone(-5) # Eastern Standard Time
    

    이것이 의미하는 것은 당신이 당신이 원하는 지역에서 먼저 (내 머리에 적어도 내가 이런 식으로 분할) 그것에 대해 생각하는 방식을 적절한 시간 설정을 얻기에 집중하고 영역에 대한 마지막에 변환 할 수 있다는 것입니다 당신은 당신의 비즈니스 로직을 확인합니다.

    이것은 또한 루비 2.3.1 작동합니다.

  11. from https://stackoverflow.com/questions/16818180/ruby-rails-change-the-timezone-of-a-time-without-changing-the-value by cc-by-sa and MIT license