~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activesupport/lib/active_support/vendor/tzinfo-0.3.12/tzinfo/timezone_period.rb

  • Committer: Michael Forrest
  • Date: 2010-10-15 16:28:50 UTC
  • Revision ID: michael.forrest@canonical.com-20101015162850-tj2vchanv0kr0dun
refrozeĀ gems

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#--
 
2
# Copyright (c) 2005-2006 Philip Ross
 
3
 
4
# Permission is hereby granted, free of charge, to any person obtaining a copy
 
5
# of this software and associated documentation files (the "Software"), to deal
 
6
# in the Software without restriction, including without limitation the rights
 
7
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
8
# copies of the Software, and to permit persons to whom the Software is
 
9
# furnished to do so, subject to the following conditions:
 
10
 
11
# The above copyright notice and this permission notice shall be included in all
 
12
# copies or substantial portions of the Software.
 
13
#
 
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
15
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
16
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
17
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
18
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
20
# THE SOFTWARE.
 
21
#++
 
22
 
 
23
require 'tzinfo/offset_rationals'
 
24
require 'tzinfo/time_or_datetime'
 
25
 
 
26
module TZInfo
 
27
  # A period of time in a timezone where the same offset from UTC applies.
 
28
  #
 
29
  # All the methods that take times accept instances of Time, DateTime or
 
30
  # integer timestamps.
 
31
  class TimezonePeriod
 
32
    # The TimezoneTransitionInfo that defines the start of this TimezonePeriod 
 
33
    # (may be nil if unbounded).
 
34
    attr_reader :start_transition
 
35
    
 
36
    # The TimezoneTransitionInfo that defines the end of this TimezonePeriod
 
37
    # (may be nil if unbounded).
 
38
    attr_reader :end_transition
 
39
    
 
40
    # The TimezoneOffsetInfo for this period.
 
41
    attr_reader :offset    
 
42
    
 
43
    # Initializes a new TimezonePeriod.
 
44
    def initialize(start_transition, end_transition, offset = nil)
 
45
      @start_transition = start_transition
 
46
      @end_transition = end_transition
 
47
      
 
48
      if offset
 
49
        raise ArgumentError, 'Offset specified with transitions' if @start_transition || @end_transition
 
50
        @offset = offset
 
51
      else
 
52
        if @start_transition 
 
53
          @offset = @start_transition.offset
 
54
        elsif @end_transition
 
55
          @offset = @end_transition.previous_offset
 
56
        else
 
57
          raise ArgumentError, 'No offset specified and no transitions to determine it from'
 
58
        end
 
59
      end
 
60
      
 
61
      @utc_total_offset_rational = nil      
 
62
    end
 
63
            
 
64
    # Base offset of the timezone from UTC (seconds).
 
65
    def utc_offset
 
66
      @offset.utc_offset
 
67
    end
 
68
    
 
69
    # Offset from the local time where daylight savings is in effect (seconds).
 
70
    # E.g.: utc_offset could be -5 hours. Normally, std_offset would be 0. 
 
71
    # During daylight savings, std_offset would typically become +1 hours.
 
72
    def std_offset
 
73
      @offset.std_offset
 
74
    end
 
75
    
 
76
    # The identifier of this period, e.g. "GMT" (Greenwich Mean Time) or "BST"
 
77
    # (British Summer Time) for "Europe/London". The returned identifier is a 
 
78
    # symbol.
 
79
    def abbreviation
 
80
      @offset.abbreviation
 
81
    end
 
82
    alias :zone_identifier :abbreviation
 
83
    
 
84
    # Total offset from UTC (seconds). Equal to utc_offset + std_offset.
 
85
    def utc_total_offset
 
86
      @offset.utc_total_offset
 
87
    end
 
88
    
 
89
    # Total offset from UTC (days). Result is a Rational.
 
90
    def utc_total_offset_rational
 
91
      unless @utc_total_offset_rational
 
92
        @utc_total_offset_rational = OffsetRationals.rational_for_offset(utc_total_offset) 
 
93
      end
 
94
      @utc_total_offset_rational
 
95
    end
 
96
    
 
97
    # The start time of the period in UTC as a DateTime. May be nil if unbounded.
 
98
    def utc_start
 
99
      @start_transition ? @start_transition.at.to_datetime : nil
 
100
    end
 
101
    
 
102
    # The end time of the period in UTC as a DateTime. May be nil if unbounded.
 
103
    def utc_end
 
104
      @end_transition ? @end_transition.at.to_datetime : nil
 
105
    end
 
106
    
 
107
    # The start time of the period in local time as a DateTime. May be nil if 
 
108
    # unbounded.
 
109
    def local_start
 
110
      @start_transition ? @start_transition.local_start.to_datetime : nil
 
111
    end
 
112
    
 
113
    # The end time of the period in local time as a DateTime. May be nil if 
 
114
    # unbounded.
 
115
    def local_end
 
116
      @end_transition ? @end_transition.local_end.to_datetime : nil
 
117
    end
 
118
    
 
119
    # true if daylight savings is in effect for this period; otherwise false.
 
120
    def dst?
 
121
      @offset.dst?
 
122
    end
 
123
    
 
124
    # true if this period is valid for the given UTC DateTime; otherwise false.
 
125
    def valid_for_utc?(utc)
 
126
      utc_after_start?(utc) && utc_before_end?(utc) 
 
127
    end
 
128
    
 
129
    # true if the given UTC DateTime is after the start of the period 
 
130
    # (inclusive); otherwise false.
 
131
    def utc_after_start?(utc)
 
132
      !@start_transition || @start_transition.at <= utc
 
133
    end
 
134
    
 
135
    # true if the given UTC DateTime is before the end of the period 
 
136
    # (exclusive); otherwise false.
 
137
    def utc_before_end?(utc)
 
138
      !@end_transition || @end_transition.at > utc
 
139
    end
 
140
    
 
141
    # true if this period is valid for the given local DateTime; otherwise false.
 
142
    def valid_for_local?(local)      
 
143
      local_after_start?(local) && local_before_end?(local) 
 
144
    end
 
145
    
 
146
    # true if the given local DateTime is after the start of the period 
 
147
    # (inclusive); otherwise false.
 
148
    def local_after_start?(local)
 
149
      !@start_transition || @start_transition.local_start <= local
 
150
    end
 
151
    
 
152
    # true if the given local DateTime is before the end of the period 
 
153
    # (exclusive); otherwise false.
 
154
    def local_before_end?(local)
 
155
      !@end_transition || @end_transition.local_end > local
 
156
    end
 
157
    
 
158
    # Converts a UTC DateTime to local time based on the offset of this period.
 
159
    def to_local(utc)
 
160
      @offset.to_local(utc)
 
161
    end
 
162
    
 
163
    # Converts a local DateTime to UTC based on the offset of this period.
 
164
    def to_utc(local)
 
165
      @offset.to_utc(local)
 
166
    end
 
167
    
 
168
    # Returns true if this TimezonePeriod is equal to p. This compares the 
 
169
    # start_transition, end_transition and offset using ==.
 
170
    def ==(p)
 
171
      p.respond_to?(:start_transition) && p.respond_to?(:end_transition) &&
 
172
        p.respond_to?(:offset) && start_transition == p.start_transition &&
 
173
        end_transition == p.end_transition && offset == p.offset
 
174
    end
 
175
    
 
176
    # Returns true if this TimezonePeriods is equal to p. This compares the
 
177
    # start_transition, end_transition and offset using eql?
 
178
    def eql?(p)
 
179
      p.respond_to?(:start_transition) && p.respond_to?(:end_transition) &&
 
180
        p.respond_to?(:offset) && start_transition.eql?(p.start_transition) &&
 
181
        end_transition.eql?(p.end_transition) && offset.eql?(p.offset)
 
182
    end
 
183
    
 
184
    # Returns a hash of this TimezonePeriod.
 
185
    def hash
 
186
      result = @start_transition.hash ^ @end_transition.hash
 
187
      result ^= @offset.hash unless @start_transition || @end_transition
 
188
      result       
 
189
    end
 
190
    
 
191
    # Returns internal object state as a programmer-readable string.
 
192
    def inspect
 
193
      result = "#<#{self.class}: #{@start_transition.inspect},#{@end_transition.inspect}"
 
194
      result << ",#{@offset.inspect}>" unless @start_transition || @end_transition
 
195
      result + '>'
 
196
    end
 
197
  end
 
198
end