Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Changeset 9006

Show
Ignore:
Timestamp:
03/11/08 04:26:20 (4 months ago)
Author:
gbuesing
Message:

TimeWithZone instances correctly enforce DST rules. Adding TimeZone#period_for_utc

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/activesupport/CHANGELOG

    r9002 r9006  
    11*SVN* 
     2 
     3* TimeWithZone instances correctly enforce DST rules. Adding TimeZone#period_for_utc [Geoff Buesing] 
    24 
    35* test_time_with_datetime_fallback expects DateTime.local_offset instead of DateTime.now.offset [Geoff Buesing] 
  • trunk/activesupport/lib/active_support/time_with_zone.rb

    r8975 r9006  
    2828    # Returns the underlying TZInfo::TimezonePeriod for the local time 
    2929    def period 
    30       @period ||= get_period_for_local 
     30      @period ||= time_zone.period_for_utc(utc) 
    3131    end 
    3232 
     
    151151    end 
    152152     
     153    %w(asctime day hour min mon sec usec wday yday year).each do |name| 
     154      define_method(name) do 
     155        time.__send__(name) 
     156      end 
     157    end 
     158    alias_method :ctime, :asctime 
     159    alias_method :mday, :day 
     160    alias_method :month, :mon 
     161     
    153162    def to_a 
    154163      time.to_a[0, 8].push(dst?, zone) 
     
    207216    # Send the missing method to time instance, and wrap result in a new TimeWithZone with the existing time_zone 
    208217    def method_missing(sym, *args, &block) 
    209       result = time.__send__(sym, *args, &block) 
    210       result = result.change_time_zone(time_zone) if result.acts_like?(:time) 
     218      result = utc.__send__(sym, *args, &block) 
     219      result = result.in_time_zone(time_zone) if result.acts_like?(:time) 
    211220      result 
    212221    end 
    213    
    214     private 
    215       def get_period_for_local 
    216         t = time 
    217         begin 
    218           time_zone.period_for_local(t, true) 
    219         rescue ::TZInfo::PeriodNotFound # failover logic from TzTime 
    220           t -= 1.hour 
    221           retry 
    222         end 
    223       end 
    224222  end 
    225223end 
  • trunk/activesupport/lib/active_support/values/time_zone.rb

    r8847 r9006  
    213213 
    214214    # Available so that TimeZone instances respond like TZInfo::Timezone instances 
     215    def period_for_utc(time) 
     216      tzinfo.period_for_utc(time) 
     217    end 
     218 
     219    # Available so that TimeZone instances respond like TZInfo::Timezone instances 
    215220    def period_for_local(time, dst=true) 
    216221      tzinfo.period_for_local(time, dst) 
  • trunk/activesupport/test/core_ext/time_with_zone_test.rb

    r8975 r9006  
    164164      twz2 = ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 2), TimeZone['UTC'] ) 
    165165      assert_equal  86_400.0,  twz2 - twz1 
     166    end 
     167     
     168    def test_plus_and_minus_enforce_spring_dst_rules 
     169      utc = Time.utc(2006,4,2,6,59,59) # == Apr 2 2006 01:59:59 EST; i.e., 1 second before daylight savings start 
     170      twz = ActiveSupport::TimeWithZone.new(utc, @time_zone) 
     171      assert_equal Time.utc(2006,4,2,1,59,59), twz.time 
     172      assert_equal false, twz.dst? 
     173      assert_equal 'EST', twz.zone 
     174      twz = twz + 1 
     175      assert_equal Time.utc(2006,4,2,3), twz.time # adding 1 sec springs forward to 3:00AM EDT 
     176      assert_equal true, twz.dst? 
     177      assert_equal 'EDT', twz.zone 
     178      twz = twz - 1 # subtracting 1 second takes goes back to 1:59:59AM EST 
     179      assert_equal Time.utc(2006,4,2,1,59,59), twz.time 
     180      assert_equal false, twz.dst? 
     181      assert_equal 'EST', twz.zone 
     182    end 
     183     
     184    def test_plus_and_minus_enforce_fall_dst_rules 
     185      utc = Time.utc(2006,10,29,5,59,59) # == Oct 29 2006 01:59:59 EST; i.e., 1 second before daylight savings end 
     186      twz = ActiveSupport::TimeWithZone.new(utc, @time_zone) 
     187      assert_equal Time.utc(2006,10,29,1,59,59), twz.time 
     188      assert_equal true, twz.dst? 
     189      assert_equal 'EDT', twz.zone 
     190      twz = twz + 1 
     191      assert_equal Time.utc(2006,10,29,1), twz.time # adding 1 sec falls back from 1:59:59 EDT to 1:00AM EST 
     192      assert_equal false, twz.dst? 
     193      assert_equal 'EST', twz.zone 
     194      twz = twz - 1 
     195      assert_equal Time.utc(2006,10,29,1,59,59), twz.time # subtracting 1 sec goes back to 1:59:59AM EDT 
     196      assert_equal true, twz.dst? 
     197      assert_equal 'EDT', twz.zone 
    166198    end 
    167199     
     
    220252       
    221253    def test_method_missing_with_non_time_return_value 
    222       assert_equal 1999, @twz.year 
    223       assert_equal 12, @twz.month 
    224       assert_equal 31, @twz.day 
     254      twz = ActiveSupport::TimeWithZone.new(Time.utc(1999,12,31,19,18,17,500), @time_zone) 
     255      assert_equal 1999, twz.year 
     256      assert_equal 12, twz.month 
     257      assert_equal 31, twz.day 
     258      assert_equal 14, twz.hour 
     259      assert_equal 18, twz.min 
     260      assert_equal 17, twz.sec 
     261      assert_equal 500, twz.usec 
    225262    end 
    226263  end