tzinfo 1.0.1 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of tzinfo might be problematic. Click here for more details.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.yardopts +6 -0
- data/{CHANGES → CHANGES.md} +121 -50
- data/{README → README.md} +48 -34
- data/Rakefile +45 -22
- data/lib/tzinfo.rb +7 -2
- data/lib/tzinfo/country.rb +23 -1
- data/lib/tzinfo/country_index_definition.rb +6 -1
- data/lib/tzinfo/country_timezone.rb +9 -1
- data/lib/tzinfo/data_source.rb +26 -5
- data/lib/tzinfo/data_timezone.rb +30 -2
- data/lib/tzinfo/data_timezone_info.rb +26 -0
- data/lib/tzinfo/info_timezone.rb +3 -1
- data/lib/tzinfo/linked_timezone.rb +30 -1
- data/lib/tzinfo/offset_rationals.rb +5 -3
- data/lib/tzinfo/ruby_core_support.rb +2 -0
- data/lib/tzinfo/ruby_country_info.rb +14 -0
- data/lib/tzinfo/ruby_data_source.rb +5 -0
- data/lib/tzinfo/time_or_datetime.rb +16 -1
- data/lib/tzinfo/timezone.rb +107 -5
- data/lib/tzinfo/timezone_definition.rb +5 -1
- data/lib/tzinfo/timezone_index_definition.rb +7 -1
- data/lib/tzinfo/{timezone_offset_info.rb → timezone_offset.rb} +12 -10
- data/lib/tzinfo/timezone_period.rb +19 -15
- data/lib/tzinfo/timezone_proxy.rb +5 -1
- data/lib/tzinfo/timezone_transition.rb +136 -0
- data/lib/tzinfo/{timezone_transition_info.rb → timezone_transition_definition.rb} +21 -57
- data/lib/tzinfo/transition_data_timezone_info.rb +81 -8
- data/lib/tzinfo/zoneinfo_country_info.rb +7 -0
- data/lib/tzinfo/zoneinfo_data_source.rb +104 -57
- data/lib/tzinfo/zoneinfo_timezone_info.rb +18 -10
- data/test/tc_country.rb +39 -1
- data/test/tc_data_timezone.rb +28 -5
- data/test/tc_linked_timezone.rb +24 -3
- data/test/tc_ruby_data_source.rb +22 -2
- data/test/tc_time_or_datetime.rb +3 -3
- data/test/tc_timezone.rb +364 -117
- data/test/tc_timezone_london.rb +25 -0
- data/test/tc_timezone_melbourne.rb +24 -0
- data/test/tc_timezone_new_york.rb +24 -0
- data/test/{tc_timezone_offset_info.rb → tc_timezone_offset.rb} +27 -27
- data/test/tc_timezone_period.rb +113 -90
- data/test/tc_timezone_transition.rb +374 -0
- data/test/tc_timezone_transition_definition.rb +306 -0
- data/test/tc_transition_data_timezone_info.rb +143 -43
- data/test/tc_zoneinfo_data_source.rb +69 -5
- data/test/tc_zoneinfo_timezone_info.rb +63 -20
- data/test/test_utils.rb +27 -7
- data/tzinfo.gemspec +21 -0
- metadata +61 -38
- metadata.gz.sig +3 -0
- data/test/tc_timezone_transition_info.rb +0 -471
- data/test/zoneinfo/UTC +0 -0
- data/test/zoneinfo/localtime +0 -0
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2013 Philip Ross
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -22,7 +22,7 @@
|
|
22
22
|
|
23
23
|
module TZInfo
|
24
24
|
# Represents an offset defined in a Timezone data file.
|
25
|
-
class
|
25
|
+
class TimezoneOffset
|
26
26
|
# The base offset of the timezone from UTC in seconds.
|
27
27
|
attr_reader :utc_offset
|
28
28
|
|
@@ -39,8 +39,8 @@ module TZInfo
|
|
39
39
|
# symbol.
|
40
40
|
attr_reader :abbreviation
|
41
41
|
|
42
|
-
# Constructs a new
|
43
|
-
#
|
42
|
+
# Constructs a new TimezoneOffset. utc_offset and std_offset are specified
|
43
|
+
# in seconds.
|
44
44
|
def initialize(utc_offset, std_offset, abbreviation)
|
45
45
|
@utc_offset = utc_offset
|
46
46
|
@std_offset = std_offset
|
@@ -54,14 +54,16 @@ module TZInfo
|
|
54
54
|
@std_offset != 0
|
55
55
|
end
|
56
56
|
|
57
|
-
# Converts a UTC DateTime to local time based on
|
57
|
+
# Converts a UTC Time, DateTime or integer timestamp to local time, based on
|
58
|
+
# the offset of this period.
|
58
59
|
def to_local(utc)
|
59
60
|
TimeOrDateTime.wrap(utc) {|wrapped|
|
60
61
|
wrapped + @utc_total_offset
|
61
62
|
}
|
62
63
|
end
|
63
64
|
|
64
|
-
# Converts a local DateTime to UTC based on the
|
65
|
+
# Converts a local Time, DateTime or integer timestamp to UTC, based on the
|
66
|
+
# offset of this period.
|
65
67
|
def to_utc(local)
|
66
68
|
TimeOrDateTime.wrap(local) {|wrapped|
|
67
69
|
wrapped - @utc_total_offset
|
@@ -69,19 +71,19 @@ module TZInfo
|
|
69
71
|
end
|
70
72
|
|
71
73
|
# Returns true if and only if toi has the same utc_offset, std_offset
|
72
|
-
# and abbreviation as this
|
74
|
+
# and abbreviation as this TimezoneOffset.
|
73
75
|
def ==(toi)
|
74
|
-
toi.kind_of?(
|
76
|
+
toi.kind_of?(TimezoneOffset) &&
|
75
77
|
utc_offset == toi.utc_offset && std_offset == toi.std_offset && abbreviation == toi.abbreviation
|
76
78
|
end
|
77
79
|
|
78
80
|
# Returns true if and only if toi has the same utc_offset, std_offset
|
79
|
-
# and abbreviation as this
|
81
|
+
# and abbreviation as this TimezoneOffset.
|
80
82
|
def eql?(toi)
|
81
83
|
self == toi
|
82
84
|
end
|
83
85
|
|
84
|
-
# Returns a hash of this
|
86
|
+
# Returns a hash of this TimezoneOffset.
|
85
87
|
def hash
|
86
88
|
utc_offset.hash ^ std_offset.hash ^ abbreviation.hash
|
87
89
|
end
|
@@ -26,21 +26,20 @@ module TZInfo
|
|
26
26
|
# All the methods that take times accept instances of Time or DateTime as well
|
27
27
|
# as Integer timestamps.
|
28
28
|
class TimezonePeriod
|
29
|
-
# The
|
29
|
+
# The TimezoneTransition that defines the start of this TimezonePeriod
|
30
30
|
# (may be nil if unbounded).
|
31
|
-
attr_reader :start_transition
|
32
|
-
protected :start_transition
|
31
|
+
attr_reader :start_transition
|
33
32
|
|
34
|
-
# The
|
33
|
+
# The TimezoneTransition that defines the end of this TimezonePeriod
|
35
34
|
# (may be nil if unbounded).
|
36
|
-
attr_reader :end_transition
|
37
|
-
protected :end_transition
|
35
|
+
attr_reader :end_transition
|
38
36
|
|
39
|
-
# The
|
40
|
-
attr_reader :offset
|
41
|
-
protected :offset
|
37
|
+
# The TimezoneOffset for this period.
|
38
|
+
attr_reader :offset
|
42
39
|
|
43
40
|
# Initializes a new TimezonePeriod.
|
41
|
+
#
|
42
|
+
# TimezonePeriod instances should not normally be constructed manually.
|
44
43
|
def initialize(start_transition, end_transition, offset = nil)
|
45
44
|
@start_transition = start_transition
|
46
45
|
@end_transition = end_transition
|
@@ -88,6 +87,11 @@ module TZInfo
|
|
88
87
|
|
89
88
|
# Total offset from UTC (days). Result is a Rational.
|
90
89
|
def utc_total_offset_rational
|
90
|
+
# Thread-safey: It is possible that the value of
|
91
|
+
# @utc_total_offset_rational may be calculated multiple times in
|
92
|
+
# concurrently executing threads. It is not worth the overhead of locking
|
93
|
+
# to ensure that @zone_identifiers is only calculated once.
|
94
|
+
|
91
95
|
unless @utc_total_offset_rational
|
92
96
|
@utc_total_offset_rational = OffsetRationals.rational_for_offset(utc_total_offset)
|
93
97
|
end
|
@@ -117,25 +121,25 @@ module TZInfo
|
|
117
121
|
# The start time of the period in local time as a DateTime. May be nil if
|
118
122
|
# unbounded.
|
119
123
|
def local_start
|
120
|
-
@start_transition ? @start_transition.
|
124
|
+
@start_transition ? @start_transition.local_start_at.to_datetime : nil
|
121
125
|
end
|
122
126
|
|
123
127
|
# The start time of the period in local time as a Time. May be nil if
|
124
128
|
# unbounded.
|
125
129
|
def local_start_time
|
126
|
-
@start_transition ? @start_transition.
|
130
|
+
@start_transition ? @start_transition.local_start_at.to_time : nil
|
127
131
|
end
|
128
132
|
|
129
133
|
# The end time of the period in local time as a DateTime. May be nil if
|
130
134
|
# unbounded.
|
131
135
|
def local_end
|
132
|
-
@end_transition ? @end_transition.
|
136
|
+
@end_transition ? @end_transition.local_end_at.to_datetime : nil
|
133
137
|
end
|
134
138
|
|
135
139
|
# The end time of the period in local time as a Time. May be nil if
|
136
140
|
# unbounded.
|
137
141
|
def local_end_time
|
138
|
-
@end_transition ? @end_transition.
|
142
|
+
@end_transition ? @end_transition.local_end_at.to_time : nil
|
139
143
|
end
|
140
144
|
|
141
145
|
# true if daylight savings is in effect for this period; otherwise false.
|
@@ -168,13 +172,13 @@ module TZInfo
|
|
168
172
|
# true if the given local DateTime is after the start of the period
|
169
173
|
# (inclusive); otherwise false.
|
170
174
|
def local_after_start?(local)
|
171
|
-
!@start_transition || @start_transition.
|
175
|
+
!@start_transition || @start_transition.local_start_at <= local
|
172
176
|
end
|
173
177
|
|
174
178
|
# true if the given local DateTime is before the end of the period
|
175
179
|
# (exclusive); otherwise false.
|
176
180
|
def local_before_end?(local)
|
177
|
-
!@end_transition || @end_transition.
|
181
|
+
!@end_transition || @end_transition.local_end_at > local
|
178
182
|
end
|
179
183
|
|
180
184
|
# Converts a UTC DateTime to local time based on the offset of this period.
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2005-
|
2
|
+
# Copyright (c) 2005-2013 Philip Ross
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -77,6 +77,10 @@ module TZInfo
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def real_timezone
|
80
|
+
# Thread-safey: It is possible that the value of @real_timezone may be
|
81
|
+
# calculated multiple times in concurrently executing threads. It is not
|
82
|
+
# worth the overhead of locking to ensure that @real_timezone is only
|
83
|
+
# calculated once.
|
80
84
|
@real_timezone ||= Timezone.get(@identifier)
|
81
85
|
end
|
82
86
|
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2006-2013 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
|
+
module TZInfo
|
24
|
+
# Represents a transition from one timezone offset to another at a particular
|
25
|
+
# date and time.
|
26
|
+
class TimezoneTransition
|
27
|
+
# The offset this transition changes to (a TimezoneOffset instance).
|
28
|
+
attr_reader :offset
|
29
|
+
|
30
|
+
# The offset this transition changes from (a TimezoneOffset instance).
|
31
|
+
attr_reader :previous_offset
|
32
|
+
|
33
|
+
# Initializes a new TimezoneTransition.
|
34
|
+
#
|
35
|
+
# TimezoneTransition instances should not normally be constructed manually.
|
36
|
+
def initialize(offset, previous_offset)
|
37
|
+
@offset = offset
|
38
|
+
@previous_offset = previous_offset
|
39
|
+
@local_end_at = nil
|
40
|
+
@local_start_at = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# A TimeOrDateTime instance representing the UTC time when this transition
|
44
|
+
# occurs.
|
45
|
+
def at
|
46
|
+
raise NotImplementedError, 'Subclasses must override at'
|
47
|
+
end
|
48
|
+
|
49
|
+
# The UTC time when this transition occurs, returned as a DateTime instance.
|
50
|
+
def datetime
|
51
|
+
at.to_datetime
|
52
|
+
end
|
53
|
+
|
54
|
+
# The UTC time when this transition occurs, returned as a Time instance.
|
55
|
+
def time
|
56
|
+
at.to_time
|
57
|
+
end
|
58
|
+
|
59
|
+
# A TimeOrDateTime instance representing the local time when this transition
|
60
|
+
# causes the previous observance to end (calculated from at using
|
61
|
+
# previous_offset).
|
62
|
+
def local_end_at
|
63
|
+
# Thread-safey: It is possible that the value of @local_end_at may be
|
64
|
+
# calculated multiple times in concurrently executing threads. It is not
|
65
|
+
# worth the overhead of locking to ensure that @local_end_at is only
|
66
|
+
# calculated once.
|
67
|
+
|
68
|
+
@local_end_at = at.add_with_convert(@previous_offset.utc_total_offset) unless @local_end_at
|
69
|
+
@local_end_at
|
70
|
+
end
|
71
|
+
|
72
|
+
# The local time when this transition causes the previous observance to end,
|
73
|
+
# returned as a DateTime instance.
|
74
|
+
def local_end
|
75
|
+
local_end_at.to_datetime
|
76
|
+
end
|
77
|
+
|
78
|
+
# The local time when this transition causes the previous observance to end,
|
79
|
+
# returned as a Time instance.
|
80
|
+
def local_end_time
|
81
|
+
local_end_at.to_time
|
82
|
+
end
|
83
|
+
|
84
|
+
# A TimeOrDateTime instance representing the local time when this transition
|
85
|
+
# causes the next observance to start (calculated from at using offset).
|
86
|
+
def local_start_at
|
87
|
+
# Thread-safey: It is possible that the value of @local_start_at may be
|
88
|
+
# calculated multiple times in concurrently executing threads. It is not
|
89
|
+
# worth the overhead of locking to ensure that @local_start_at is only
|
90
|
+
# calculated once.
|
91
|
+
|
92
|
+
@local_start_at = at.add_with_convert(@offset.utc_total_offset) unless @local_start_at
|
93
|
+
@local_start_at
|
94
|
+
end
|
95
|
+
|
96
|
+
# The local time when this transition causes the next observance to start,
|
97
|
+
# returned as a DateTime instance.
|
98
|
+
def local_start
|
99
|
+
local_start_at.to_datetime
|
100
|
+
end
|
101
|
+
|
102
|
+
# The local time when this transition causes the next observance to start,
|
103
|
+
# returned as a Time instance.
|
104
|
+
def local_start_time
|
105
|
+
local_start_at.to_time
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns true if this TimezoneTransition is equal to the given
|
109
|
+
# TimezoneTransition. Two TimezoneTransition instances are
|
110
|
+
# considered to be equal by == if offset, previous_offset and at are all
|
111
|
+
# equal.
|
112
|
+
def ==(tti)
|
113
|
+
tti.kind_of?(TimezoneTransition) &&
|
114
|
+
offset == tti.offset && previous_offset == tti.previous_offset && at == tti.at
|
115
|
+
end
|
116
|
+
|
117
|
+
# Returns true if this TimezoneTransition is equal to the given
|
118
|
+
# TimezoneTransition. Two TimezoneTransition instances are
|
119
|
+
# considered to be equal by eql? if offset, previous_offset and at are all
|
120
|
+
# equal and the type used to define at in both instances is the same.
|
121
|
+
def eql?(tti)
|
122
|
+
tti.kind_of?(TimezoneTransition) &&
|
123
|
+
offset == tti.offset && previous_offset == tti.previous_offset && at.eql?(tti.at)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns a hash of this TimezoneTransition instance.
|
127
|
+
def hash
|
128
|
+
@offset.hash ^ @previous_offset.hash ^ at.hash
|
129
|
+
end
|
130
|
+
|
131
|
+
# Returns internal object state as a programmer-readable string.
|
132
|
+
def inspect
|
133
|
+
"#<#{self.class}: #{at.inspect},#{@offset.inspect}>"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c)
|
2
|
+
# Copyright (c) 2013 Philip Ross
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -20,18 +20,12 @@
|
|
20
20
|
# THE SOFTWARE.
|
21
21
|
#++
|
22
22
|
|
23
|
-
require 'date'
|
24
|
-
|
25
23
|
module TZInfo
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
# The offset this transition changes from (a TimezoneOffsetInfo instance).
|
33
|
-
attr_reader :previous_offset
|
34
|
-
|
24
|
+
# A TimezoneTransition defined by as integer timestamp, as a rational to
|
25
|
+
# create a DateTime or as both.
|
26
|
+
#
|
27
|
+
# @private
|
28
|
+
class TimezoneTransitionDefinition < TimezoneTransition #:nodoc:
|
35
29
|
# The numerator of the DateTime if the transition time is defined as a
|
36
30
|
# DateTime, otherwise the transition time as a timestamp.
|
37
31
|
attr_reader :numerator_or_time
|
@@ -42,11 +36,11 @@ module TZInfo
|
|
42
36
|
attr_reader :denominator
|
43
37
|
protected :denominator
|
44
38
|
|
45
|
-
# Creates a new
|
46
|
-
# previous_offset (both
|
39
|
+
# Creates a new TimezoneTransitionDefinition with the given offset,
|
40
|
+
# previous_offset (both TimezoneOffset instances) and UTC time.
|
47
41
|
#
|
48
42
|
# The time can be specified as a timestamp, as a rational to create a
|
49
|
-
# DateTime or as both.
|
43
|
+
# DateTime, or as both.
|
50
44
|
#
|
51
45
|
# If both a timestamp and rational are given, then the rational will only
|
52
46
|
# be used if the timestamp falls outside of the range of Time on the
|
@@ -54,13 +48,12 @@ module TZInfo
|
|
54
48
|
#
|
55
49
|
# DateTimes are created from the rational as follows:
|
56
50
|
#
|
57
|
-
# RubyCoreSupport.datetime_new!(RubyCoreSupport.rational_new!(
|
51
|
+
# RubyCoreSupport.datetime_new!(RubyCoreSupport.rational_new!(numerator, denominator), 0, Date::ITALY)
|
58
52
|
#
|
59
53
|
# For performance reasons, the numerator and denominator must be specified
|
60
54
|
# in their lowest form.
|
61
55
|
def initialize(offset, previous_offset, numerator_or_timestamp, denominator_or_numerator = nil, denominator = nil)
|
62
|
-
|
63
|
-
@previous_offset = previous_offset
|
56
|
+
super(offset, previous_offset)
|
64
57
|
|
65
58
|
if denominator
|
66
59
|
numerator = denominator_or_numerator
|
@@ -90,13 +83,15 @@ module TZInfo
|
|
90
83
|
end
|
91
84
|
|
92
85
|
@at = nil
|
93
|
-
@local_end = nil
|
94
|
-
@local_start = nil
|
95
86
|
end
|
96
87
|
|
97
88
|
# A TimeOrDateTime instance representing the UTC time when this transition
|
98
89
|
# occurs.
|
99
90
|
def at
|
91
|
+
# Thread-safey: It is possible that the value of @at may be calculated
|
92
|
+
# multiple times in concurrently executing threads. It is not worth the
|
93
|
+
# overhead of locking to ensure that @at is only calculated once.
|
94
|
+
|
100
95
|
unless @at
|
101
96
|
unless @denominator
|
102
97
|
@at = TimeOrDateTime.new(@numerator_or_time)
|
@@ -110,50 +105,19 @@ module TZInfo
|
|
110
105
|
@at
|
111
106
|
end
|
112
107
|
|
113
|
-
#
|
114
|
-
#
|
115
|
-
# previous_offset
|
116
|
-
|
117
|
-
@local_end = at.add_with_convert(@previous_offset.utc_total_offset) unless @local_end
|
118
|
-
@local_end
|
119
|
-
end
|
120
|
-
|
121
|
-
# A TimeOrDateTime instance representing the local time when this transition
|
122
|
-
# causes the next observance to start (calculated from at using offset).
|
123
|
-
def local_start
|
124
|
-
@local_start = at.add_with_convert(@offset.utc_total_offset) unless @local_start
|
125
|
-
@local_start
|
126
|
-
end
|
127
|
-
|
128
|
-
# Returns true if this TimezoneTransitionInfo is equal to the given
|
129
|
-
# TimezoneTransitionInfo. Two TimezoneTransitionInfo instances are
|
130
|
-
# considered to be equal by == if offset, previous_offset and at are all
|
131
|
-
# equal.
|
132
|
-
def ==(tti)
|
133
|
-
tti.kind_of?(TimezoneTransitionInfo) &&
|
134
|
-
offset == tti.offset && previous_offset == tti.previous_offset && at == tti.at
|
135
|
-
end
|
136
|
-
|
137
|
-
# Returns true if this TimezoneTransitionInfo is equal to the given
|
138
|
-
# TimezoneTransitionInfo. Two TimezoneTransitionInfo instances are
|
139
|
-
# considered to be equal by eql? if offset, previous_offset,
|
140
|
-
# numerator_or_time and denominator are all equal. This is stronger than ==,
|
141
|
-
# which just requires the at times to be equal regardless of how they were
|
142
|
-
# originally specified.
|
108
|
+
# Returns true if this TimezoneTransitionDefinition is equal to the given
|
109
|
+
# TimezoneTransitionDefinition. Two TimezoneTransitionDefinition instances
|
110
|
+
# are considered to be equal by eql? if offset, previous_offset,
|
111
|
+
# numerator_or_time and denominator are all equal.
|
143
112
|
def eql?(tti)
|
144
|
-
tti.kind_of?(
|
113
|
+
tti.kind_of?(TimezoneTransitionDefinition) &&
|
145
114
|
offset == tti.offset && previous_offset == tti.previous_offset &&
|
146
115
|
numerator_or_time == tti.numerator_or_time && denominator == tti.denominator
|
147
116
|
end
|
148
117
|
|
149
|
-
# Returns a hash of this
|
118
|
+
# Returns a hash of this TimezoneTransitionDefinition instance.
|
150
119
|
def hash
|
151
120
|
@offset.hash ^ @previous_offset.hash ^ @numerator_or_time.hash ^ @denominator.hash
|
152
121
|
end
|
153
|
-
|
154
|
-
# Returns internal object state as a programmer-readable string.
|
155
|
-
def inspect
|
156
|
-
"#<#{self.class}: #{at.inspect},#{@offset.inspect}>"
|
157
|
-
end
|
158
122
|
end
|
159
123
|
end
|
@@ -27,7 +27,9 @@ module TZInfo
|
|
27
27
|
end
|
28
28
|
|
29
29
|
# Represents a data timezone defined by a set of offsets and a set
|
30
|
-
# of transitions
|
30
|
+
# of transitions.
|
31
|
+
#
|
32
|
+
# @private
|
31
33
|
class TransitionDataTimezoneInfo < DataTimezoneInfo #:nodoc:
|
32
34
|
|
33
35
|
# Constructs a new TransitionDataTimezoneInfo with its identifier.
|
@@ -52,7 +54,7 @@ module TZInfo
|
|
52
54
|
def offset(id, utc_offset, std_offset, abbreviation)
|
53
55
|
raise ArgumentError, 'Offset already defined' if @offsets.has_key?(id)
|
54
56
|
|
55
|
-
offset =
|
57
|
+
offset = TimezoneOffset.new(utc_offset, std_offset, abbreviation)
|
56
58
|
@offsets[id] = offset
|
57
59
|
@previous_offset = offset unless @previous_offset
|
58
60
|
end
|
@@ -62,7 +64,7 @@ module TZInfo
|
|
62
64
|
# offset_id refers to an id defined with offset. ArgumentError will be
|
63
65
|
# raised if the offset_id cannot be found. numerator_or_time and
|
64
66
|
# denomiator specify the time the transition occurs as. See
|
65
|
-
#
|
67
|
+
# TimezoneTransition for more detail about specifying times.
|
66
68
|
def transition(year, month, offset_id, numerator_or_timestamp, denominator_or_numerator = nil, denominator = nil)
|
67
69
|
offset = @offsets[offset_id]
|
68
70
|
raise ArgumentError, 'Offset not found' unless offset
|
@@ -87,7 +89,7 @@ module TZInfo
|
|
87
89
|
@start_month = month
|
88
90
|
end
|
89
91
|
|
90
|
-
@transitions <<
|
92
|
+
@transitions << TimezoneTransitionDefinition.new(offset, @previous_offset,
|
91
93
|
numerator_or_timestamp, denominator_or_numerator, denominator)
|
92
94
|
@last_year = year
|
93
95
|
@last_month = month
|
@@ -148,9 +150,9 @@ module TZInfo
|
|
148
150
|
result = []
|
149
151
|
|
150
152
|
start_index = transition_after_start(index - 1)
|
151
|
-
if start_index && @transitions[start_index].
|
153
|
+
if start_index && @transitions[start_index].local_end_at > local
|
152
154
|
if start_index > 0
|
153
|
-
if @transitions[start_index - 1].
|
155
|
+
if @transitions[start_index - 1].local_start_at <= local
|
154
156
|
result << TimezonePeriod.new(@transitions[start_index - 1], @transitions[start_index])
|
155
157
|
end
|
156
158
|
else
|
@@ -164,9 +166,9 @@ module TZInfo
|
|
164
166
|
start_index = end_index unless start_index
|
165
167
|
|
166
168
|
start_index.upto(transition_before_end(index + 1)) do |i|
|
167
|
-
if @transitions[i].
|
169
|
+
if @transitions[i].local_start_at <= local
|
168
170
|
if i + 1 < @transitions.length
|
169
|
-
if @transitions[i + 1].
|
171
|
+
if @transitions[i + 1].local_end_at > local
|
170
172
|
result << TimezonePeriod.new(@transitions[i], @transitions[i + 1])
|
171
173
|
end
|
172
174
|
else
|
@@ -183,6 +185,77 @@ module TZInfo
|
|
183
185
|
end
|
184
186
|
end
|
185
187
|
|
188
|
+
# Returns an Array of TimezoneTransition instances representing the times
|
189
|
+
# where the UTC offset of the timezone changes.
|
190
|
+
#
|
191
|
+
# Transitions are returned up to a given date and time up to a given date
|
192
|
+
# and time, specified in UTC (utc_to).
|
193
|
+
#
|
194
|
+
# A from date and time may also be supplied using the utc_from parameter
|
195
|
+
# (also specified in UTC). If utc_from is not nil, only transitions from
|
196
|
+
# that date and time onwards will be returned.
|
197
|
+
#
|
198
|
+
# Comparisons with utc_to are exclusive. Comparisons with utc_from are
|
199
|
+
# inclusive. If a transition falls precisely on utc_to, it will be excluded.
|
200
|
+
# If a transition falls on utc_from, it will be included.
|
201
|
+
#
|
202
|
+
# Transitions returned are ordered by when they occur, from earliest to
|
203
|
+
# latest.
|
204
|
+
#
|
205
|
+
# utc_to and utc_from can be specified using either DateTime, Time or
|
206
|
+
# integer timestamps (Time.to_i).
|
207
|
+
#
|
208
|
+
# If utc_from is specified and utc_to is not greater than utc_from, then
|
209
|
+
# transitions_up_to raises an ArgumentError exception.
|
210
|
+
def transitions_up_to(utc_to, utc_from = nil)
|
211
|
+
utc_to = TimeOrDateTime.wrap(utc_to)
|
212
|
+
utc_from = utc_from ? TimeOrDateTime.wrap(utc_from) : nil
|
213
|
+
|
214
|
+
if utc_from && utc_to <= utc_from
|
215
|
+
raise ArgumentError, 'utc_to must be greater than utc_from'
|
216
|
+
end
|
217
|
+
|
218
|
+
unless @transitions.empty?
|
219
|
+
if utc_from
|
220
|
+
from = transition_after_start(transition_index(utc_from.year, utc_from.mon))
|
221
|
+
|
222
|
+
if from
|
223
|
+
while from < @transitions.length && @transitions[from].at < utc_from
|
224
|
+
from += 1
|
225
|
+
end
|
226
|
+
|
227
|
+
if from >= @transitions.length
|
228
|
+
return []
|
229
|
+
end
|
230
|
+
else
|
231
|
+
# utc_from is later than last transition.
|
232
|
+
return []
|
233
|
+
end
|
234
|
+
else
|
235
|
+
from = 0
|
236
|
+
end
|
237
|
+
|
238
|
+
to = transition_before_end(transition_index(utc_to.year, utc_to.mon))
|
239
|
+
|
240
|
+
if to
|
241
|
+
while to >= 0 && @transitions[to].at >= utc_to
|
242
|
+
to -= 1
|
243
|
+
end
|
244
|
+
|
245
|
+
if to < 0
|
246
|
+
return []
|
247
|
+
end
|
248
|
+
else
|
249
|
+
# utc_to is earlier than first transition.
|
250
|
+
return []
|
251
|
+
end
|
252
|
+
|
253
|
+
@transitions[from..to]
|
254
|
+
else
|
255
|
+
[]
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
186
259
|
private
|
187
260
|
# Returns the index into the @transitions_index array for a given year
|
188
261
|
# and month.
|