tzinfo 1.2.7 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.yardopts +3 -0
  5. data/CHANGES.md +489 -382
  6. data/LICENSE +12 -12
  7. data/README.md +368 -114
  8. data/lib/tzinfo.rb +59 -29
  9. data/lib/tzinfo/country.rb +141 -129
  10. data/lib/tzinfo/country_timezone.rb +70 -112
  11. data/lib/tzinfo/data_source.rb +389 -144
  12. data/lib/tzinfo/data_sources.rb +8 -0
  13. data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
  14. data/lib/tzinfo/data_sources/country_info.rb +42 -0
  15. data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
  16. data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
  17. data/lib/tzinfo/data_sources/ruby_data_source.rb +145 -0
  18. data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
  19. data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
  20. data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +577 -0
  21. data/lib/tzinfo/data_sources/zoneinfo_reader.rb +288 -0
  22. data/lib/tzinfo/data_timezone.rb +33 -47
  23. data/lib/tzinfo/datetime_with_offset.rb +153 -0
  24. data/lib/tzinfo/format1.rb +10 -0
  25. data/lib/tzinfo/format1/country_definer.rb +17 -0
  26. data/lib/tzinfo/format1/country_index_definition.rb +64 -0
  27. data/lib/tzinfo/format1/timezone_definer.rb +64 -0
  28. data/lib/tzinfo/format1/timezone_definition.rb +39 -0
  29. data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
  30. data/lib/tzinfo/format2.rb +10 -0
  31. data/lib/tzinfo/format2/country_definer.rb +68 -0
  32. data/lib/tzinfo/format2/country_index_definer.rb +68 -0
  33. data/lib/tzinfo/format2/country_index_definition.rb +46 -0
  34. data/lib/tzinfo/format2/timezone_definer.rb +94 -0
  35. data/lib/tzinfo/format2/timezone_definition.rb +73 -0
  36. data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
  37. data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
  38. data/lib/tzinfo/info_timezone.rb +26 -21
  39. data/lib/tzinfo/linked_timezone.rb +33 -52
  40. data/lib/tzinfo/offset_timezone_period.rb +42 -0
  41. data/lib/tzinfo/string_deduper.rb +118 -0
  42. data/lib/tzinfo/time_with_offset.rb +128 -0
  43. data/lib/tzinfo/timestamp.rb +548 -0
  44. data/lib/tzinfo/timestamp_with_offset.rb +85 -0
  45. data/lib/tzinfo/timezone.rb +989 -502
  46. data/lib/tzinfo/timezone_offset.rb +84 -74
  47. data/lib/tzinfo/timezone_period.rb +151 -217
  48. data/lib/tzinfo/timezone_proxy.rb +70 -79
  49. data/lib/tzinfo/timezone_transition.rb +77 -109
  50. data/lib/tzinfo/transitions_timezone_period.rb +63 -0
  51. data/lib/tzinfo/untaint_ext.rb +18 -0
  52. data/lib/tzinfo/version.rb +7 -0
  53. data/lib/tzinfo/with_offset.rb +61 -0
  54. metadata +42 -98
  55. metadata.gz.sig +0 -0
  56. data/Rakefile +0 -107
  57. data/lib/tzinfo/country_index_definition.rb +0 -31
  58. data/lib/tzinfo/country_info.rb +0 -42
  59. data/lib/tzinfo/data_timezone_info.rb +0 -55
  60. data/lib/tzinfo/linked_timezone_info.rb +0 -26
  61. data/lib/tzinfo/offset_rationals.rb +0 -77
  62. data/lib/tzinfo/ruby_core_support.rb +0 -169
  63. data/lib/tzinfo/ruby_country_info.rb +0 -74
  64. data/lib/tzinfo/ruby_data_source.rb +0 -140
  65. data/lib/tzinfo/time_or_datetime.rb +0 -340
  66. data/lib/tzinfo/timezone_definition.rb +0 -36
  67. data/lib/tzinfo/timezone_index_definition.rb +0 -54
  68. data/lib/tzinfo/timezone_info.rb +0 -30
  69. data/lib/tzinfo/timezone_transition_definition.rb +0 -104
  70. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  71. data/lib/tzinfo/zoneinfo_country_info.rb +0 -37
  72. data/lib/tzinfo/zoneinfo_data_source.rb +0 -496
  73. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -300
  74. data/test/tc_country.rb +0 -238
  75. data/test/tc_country_index_definition.rb +0 -69
  76. data/test/tc_country_info.rb +0 -16
  77. data/test/tc_country_timezone.rb +0 -173
  78. data/test/tc_data_source.rb +0 -218
  79. data/test/tc_data_timezone.rb +0 -99
  80. data/test/tc_data_timezone_info.rb +0 -18
  81. data/test/tc_info_timezone.rb +0 -34
  82. data/test/tc_linked_timezone.rb +0 -155
  83. data/test/tc_linked_timezone_info.rb +0 -23
  84. data/test/tc_offset_rationals.rb +0 -23
  85. data/test/tc_ruby_core_support.rb +0 -168
  86. data/test/tc_ruby_country_info.rb +0 -110
  87. data/test/tc_ruby_data_source.rb +0 -167
  88. data/test/tc_time_or_datetime.rb +0 -660
  89. data/test/tc_timezone.rb +0 -1361
  90. data/test/tc_timezone_definition.rb +0 -113
  91. data/test/tc_timezone_index_definition.rb +0 -73
  92. data/test/tc_timezone_info.rb +0 -11
  93. data/test/tc_timezone_london.rb +0 -143
  94. data/test/tc_timezone_melbourne.rb +0 -142
  95. data/test/tc_timezone_new_york.rb +0 -142
  96. data/test/tc_timezone_offset.rb +0 -126
  97. data/test/tc_timezone_period.rb +0 -555
  98. data/test/tc_timezone_proxy.rb +0 -136
  99. data/test/tc_timezone_transition.rb +0 -366
  100. data/test/tc_timezone_transition_definition.rb +0 -295
  101. data/test/tc_timezone_utc.rb +0 -27
  102. data/test/tc_transition_data_timezone_info.rb +0 -433
  103. data/test/tc_zoneinfo_country_info.rb +0 -78
  104. data/test/tc_zoneinfo_data_source.rb +0 -1204
  105. data/test/tc_zoneinfo_timezone_info.rb +0 -1236
  106. data/test/test_utils.rb +0 -192
  107. data/test/ts_all.rb +0 -7
  108. data/test/ts_all_ruby.rb +0 -5
  109. data/test/ts_all_zoneinfo.rb +0 -9
  110. data/test/tzinfo-data/tzinfo/data.rb +0 -8
  111. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
  112. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -315
  113. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -218
  114. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
  115. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
  116. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
  117. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
  118. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -261
  119. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -186
  120. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -321
  121. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -265
  122. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -220
  123. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
  124. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -927
  125. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -596
  126. data/test/tzinfo-data/tzinfo/data/version.rb +0 -14
  127. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  128. data/test/zoneinfo/America/New_York +0 -0
  129. data/test/zoneinfo/Australia/Melbourne +0 -0
  130. data/test/zoneinfo/EST +0 -0
  131. data/test/zoneinfo/Etc/UTC +0 -0
  132. data/test/zoneinfo/Europe/Amsterdam +0 -0
  133. data/test/zoneinfo/Europe/Andorra +0 -0
  134. data/test/zoneinfo/Europe/London +0 -0
  135. data/test/zoneinfo/Europe/Paris +0 -0
  136. data/test/zoneinfo/Europe/Prague +0 -0
  137. data/test/zoneinfo/Factory +0 -0
  138. data/test/zoneinfo/iso3166.tab +0 -275
  139. data/test/zoneinfo/leapseconds +0 -61
  140. data/test/zoneinfo/posix/Europe/London +0 -0
  141. data/test/zoneinfo/posixrules +0 -0
  142. data/test/zoneinfo/right/Europe/London +0 -0
  143. data/test/zoneinfo/zone.tab +0 -439
  144. data/test/zoneinfo/zone1970.tab +0 -369
  145. data/tzinfo.gemspec +0 -21
@@ -1,105 +1,96 @@
1
+ # encoding: UTF-8
2
+
1
3
  module TZInfo
2
4
 
3
- # A proxy class representing a timezone with a given identifier. TimezoneProxy
4
- # inherits from Timezone and can be treated like any Timezone loaded with
5
- # Timezone.get.
5
+ # A proxy class standing in for a {Timezone} with a given identifier.
6
+ # {TimezoneProxy} inherits from {Timezone} and can be treated identically to
7
+ # {Timezone} instances loaded with {Timezone.get}.
8
+ #
9
+ # {TimezoneProxy} instances are used to avoid the performance overhead of
10
+ # loading time zone data into memory, for example, by {Timezone.all}.
6
11
  #
7
- # The first time an attempt is made to access the data for the timezone, the
8
- # real Timezone is loaded. If the proxy's identifier was not valid, then an
9
- # exception will be raised at this point.
12
+ # The first time an attempt is made to access the data for the time zone, the
13
+ # real {Timezone} will be loaded is loaded. If the proxy's identifier was not
14
+ # valid, then an exception will be raised at this point.
10
15
  class TimezoneProxy < Timezone
11
- # Construct a new TimezoneProxy for the given identifier. The identifier
12
- # is not checked when constructing the proxy. It will be validated on the
13
- # when the real Timezone is loaded.
14
- def self.new(identifier)
15
- # Need to override new to undo the behaviour introduced in Timezone#new.
16
- tzp = super()
17
- tzp.send(:setup, identifier)
18
- tzp
16
+ # Initializes a new {TimezoneProxy}.
17
+ #
18
+ # The `identifier` parameter is not checked when initializing the proxy. It
19
+ # will be validated when the real {Timezone} instance is loaded.
20
+ #
21
+ # @param identifier [String] an IANA Time Zone Database time zone
22
+ # identifier.
23
+ def initialize(identifier)
24
+ super()
25
+ @identifier = identifier
26
+ @real_timezone = nil
19
27
  end
20
-
21
- # The identifier of the timezone, e.g. "Europe/Paris".
28
+
29
+ # (see Timezone#identifier)
22
30
  def identifier
23
31
  @real_timezone ? @real_timezone.identifier : @identifier
24
32
  end
25
-
26
- # Returns the TimezonePeriod for the given UTC time. utc can either be
27
- # a DateTime, Time or integer timestamp (Time.to_i). Any timezone
28
- # information in utc is ignored (it is treated as a UTC time).
29
- def period_for_utc(utc)
30
- real_timezone.period_for_utc(utc)
33
+
34
+ # (see Timezone#period_for)
35
+ def period_for(time)
36
+ real_timezone.period_for_utc(time)
31
37
  end
32
-
33
- # Returns the set of TimezonePeriod instances that are valid for the given
34
- # local time as an array. If you just want a single period, use
35
- # period_for_local instead and specify how abiguities should be resolved.
36
- # Returns an empty array if no periods are found for the given time.
37
- def periods_for_local(local)
38
- real_timezone.periods_for_local(local)
38
+
39
+ # (see Timezone#periods_for_local)
40
+ def periods_for_local(local_time)
41
+ real_timezone.periods_for_local(local_time)
39
42
  end
40
-
41
- # Returns an Array of TimezoneTransition instances representing the times
42
- # where the UTC offset of the timezone changes.
43
- #
44
- # Transitions are returned up to a given date and time up to a given date
45
- # and time (to).
46
- #
47
- # A from date and time may also be supplied using the from parameter. If
48
- # from is not nil, only transitions from that date and time onwards will be
49
- # returned.
50
- #
51
- # Comparisons with to are exclusive. Comparisons with from are inclusive.
52
- # If a transition falls precisely on to, it will be excluded. If a
53
- # transition falls on from, it will be included.
54
- #
55
- # Transitions returned are ordered by when they occur, from earliest to
56
- # latest.
57
- #
58
- # to and from can be specified using either a Time, DateTime, Time or
59
- # Timestamp.
60
- #
61
- # If from is specified and to is not greater than from, then an
62
- # ArgumentError exception is raised.
63
- #
64
- # ArgumentError is raised if to is nil or of either to or from are
65
- # Timestamps with unspecified offsets.
43
+
44
+ # (see Timezone#transitions_up_to)
66
45
  def transitions_up_to(to, from = nil)
67
46
  real_timezone.transitions_up_to(to, from)
68
47
  end
69
48
 
70
- # Returns the canonical zone for this Timezone.
49
+ # (see Timezone#canonical_zone)
71
50
  def canonical_zone
72
51
  real_timezone.canonical_zone
73
52
  end
74
-
75
- # Dumps this TimezoneProxy for marshalling.
53
+
54
+ # Returns a serialized representation of this {TimezoneProxy}. This method
55
+ # is called when using `Marshal.dump` with an instance of {TimezoneProxy}.
56
+ #
57
+ # @param limit [Integer] the maximum depth to dump - ignored. @return
58
+ # [String] a serialized representation of this {TimezoneProxy}.
59
+ # @return [String] a serialized representation of this {TimezoneProxy}.
76
60
  def _dump(limit)
77
61
  identifier
78
62
  end
79
-
80
- # Loads a marshalled TimezoneProxy.
63
+
64
+ # Loads a {TimezoneProxy} from the serialized representation returned by
65
+ # {_dump}. This is method is called when using `Marshal.load` or
66
+ # `Marshal.restore` to restore a serialized {Timezone}.
67
+ #
68
+ # @param data [String] a serialized representation of a {TimezoneProxy}.
69
+ # @return [TimezoneProxy] the result of converting `data` back into a
70
+ # {TimezoneProxy}.
81
71
  def self._load(data)
82
72
  TimezoneProxy.new(data)
83
73
  end
84
-
74
+
85
75
  private
86
- def setup(identifier)
87
- @identifier = identifier
88
- @real_timezone = nil
89
- end
90
-
91
- def real_timezone
92
- # Thread-safety: It is possible that the value of @real_timezone may be
93
- # calculated multiple times in concurrently executing threads. It is not
94
- # worth the overhead of locking to ensure that @real_timezone is only
95
- # calculated once.
96
- unless @real_timezone
97
- result = Timezone.get(@identifier)
98
- return result if frozen?
99
- @real_timezone = result
100
- end
101
76
 
102
- @real_timezone
103
- end
104
- end
77
+ # Returns the real {Timezone} instance being proxied.
78
+ #
79
+ # The real {Timezone} is loaded using {Timezone.get} on the first access.
80
+ #
81
+ # @return [Timezone] the real {Timezone} instance being proxied.
82
+ def real_timezone
83
+ # Thread-safety: It is possible that the value of @real_timezone may be
84
+ # calculated multiple times in concurrently executing threads. It is not
85
+ # worth the overhead of locking to ensure that @real_timezone is only
86
+ # calculated once.
87
+ unless @real_timezone
88
+ result = Timezone.get(@identifier)
89
+ return result if frozen?
90
+ @real_timezone = result
91
+ end
92
+
93
+ @real_timezone
94
+ end
95
+ end
105
96
  end
@@ -1,130 +1,98 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
1
4
  module TZInfo
2
- # Represents a transition from one timezone offset to another at a particular
3
- # date and time.
5
+ # Represents a transition from one observed UTC offset ({TimezoneOffset} to
6
+ # another for a time zone.
4
7
  class TimezoneTransition
5
- # The offset this transition changes to (a TimezoneOffset instance).
8
+ # @return [TimezoneOffset] the offset this transition changes to.
6
9
  attr_reader :offset
7
-
8
- # The offset this transition changes from (a TimezoneOffset instance).
10
+
11
+ # @return [TimezoneOffset] the offset this transition changes from.
9
12
  attr_reader :previous_offset
10
-
11
- # Initializes a new TimezoneTransition.
13
+
14
+ # When this transition occurs as an `Integer` number of seconds since
15
+ # 1970-01-01 00:00:00 UTC ignoring leap seconds (i.e. each day is treated as
16
+ # if it were 86,400 seconds long). Equivalent to the result of calling the
17
+ # {Timestamp#value value} method on the {Timestamp} returned by {at}.
18
+ #
19
+ # @return [Integer] when this transition occurs as a number of seconds since
20
+ # 1970-01-01 00:00:00 UTC ignoring leap seconds.
21
+ attr_reader :timestamp_value
22
+
23
+ # Initializes a new {TimezoneTransition}.
24
+ #
25
+ # {TimezoneTransition} instances should not normally be constructed
26
+ # manually.
12
27
  #
13
- # TimezoneTransition instances should not normally be constructed manually.
14
- def initialize(offset, previous_offset)
28
+ # @param offset [TimezoneOffset] the offset the transition changes to.
29
+ # @param previous_offset [TimezoneOffset] the offset the transition changes
30
+ # from.
31
+ # @param timestamp_value [Integer] when the transition occurs as a
32
+ # number of seconds since 1970-01-01 00:00:00 UTC ignoring leap seconds
33
+ # (i.e. each day is treated as if it were 86,400 seconds long).
34
+ def initialize(offset, previous_offset, timestamp_value)
15
35
  @offset = offset
16
36
  @previous_offset = previous_offset
17
- @local_end_at = nil
18
- @local_start_at = nil
37
+ @timestamp_value = timestamp_value
19
38
  end
20
-
21
- # A TimeOrDateTime instance representing the UTC time when this transition
22
- # occurs.
39
+
40
+ # Returns a {Timestamp} instance representing the UTC time when this
41
+ # transition occurs.
42
+ #
43
+ # To obtain the result as a `Time` or `DateTime`, call either
44
+ # {Timestamp#to_time to_time} or {Timestamp#to_datetime to_datetime} on the
45
+ # {Timestamp} instance that is returned.
46
+ #
47
+ # @return [Timestamp] the UTC time when this transition occurs.
23
48
  def at
24
- raise_not_implemented('at')
25
- end
26
-
27
- # The UTC time when this transition occurs, returned as a DateTime instance.
28
- def datetime
29
- at.to_datetime
49
+ Timestamp.utc(@timestamp_value)
30
50
  end
31
-
32
- # The UTC time when this transition occurs, returned as a Time instance.
33
- def time
34
- at.to_time
35
- end
36
-
37
- # A TimeOrDateTime instance representing the local time when this transition
38
- # causes the previous observance to end (calculated from at using
39
- # previous_offset).
40
- def local_end_at
41
- # Thread-safety: It is possible that the value of @local_end_at may be
42
- # calculated multiple times in concurrently executing threads. It is not
43
- # worth the overhead of locking to ensure that @local_end_at is only
44
- # calculated once.
45
-
46
- unless @local_end_at
47
- result = at.add_with_convert(@previous_offset.utc_total_offset)
48
- return result if frozen?
49
- @local_end_at = result
50
- end
51
51
 
52
- @local_end_at
53
- end
54
-
55
- # The local time when this transition causes the previous observance to end,
56
- # returned as a DateTime instance.
57
- def local_end
58
- local_end_at.to_datetime
59
- end
60
-
61
- # The local time when this transition causes the previous observance to end,
62
- # returned as a Time instance.
63
- def local_end_time
64
- local_end_at.to_time
52
+ # Returns a {TimestampWithOffset} instance representing the local time when
53
+ # this transition causes the previous observance to end (calculated from
54
+ # {at} using {previous_offset}).
55
+ #
56
+ # To obtain the result as a `Time` or `DateTime`, call either
57
+ # {TimestampWithOffset#to_time to_time} or {TimestampWithOffset#to_datetime
58
+ # to_datetime} on the {TimestampWithOffset} instance that is returned.
59
+ #
60
+ # @return [TimestampWithOffset] the local time when this transition causes
61
+ # the previous observance to end.
62
+ def local_end_at
63
+ TimestampWithOffset.new(@timestamp_value, 0, @previous_offset.observed_utc_offset).set_timezone_offset(@previous_offset)
65
64
  end
66
-
67
- # A TimeOrDateTime instance representing the local time when this transition
68
- # causes the next observance to start (calculated from at using offset).
69
- def local_start_at
70
- # Thread-safety: It is possible that the value of @local_start_at may be
71
- # calculated multiple times in concurrently executing threads. It is not
72
- # worth the overhead of locking to ensure that @local_start_at is only
73
- # calculated once.
74
-
75
- unless @local_start_at
76
- result = at.add_with_convert(@offset.utc_total_offset)
77
- return result if frozen?
78
- @local_start_at = result
79
- end
80
65
 
81
- @local_start_at
82
- end
83
-
84
- # The local time when this transition causes the next observance to start,
85
- # returned as a DateTime instance.
86
- def local_start
87
- local_start_at.to_datetime
88
- end
89
-
90
- # The local time when this transition causes the next observance to start,
91
- # returned as a Time instance.
92
- def local_start_time
93
- local_start_at.to_time
66
+ # Returns a {TimestampWithOffset} instance representing the local time when
67
+ # this transition causes the next observance to start (calculated from {at}
68
+ # using {offset}).
69
+ #
70
+ # To obtain the result as a `Time` or `DateTime`, call either
71
+ # {TimestampWithOffset#to_time to_time} or {TimestampWithOffset#to_datetime
72
+ # to_datetime} on the {TimestampWithOffset} instance that is returned.
73
+ #
74
+ # @return [TimestampWithOffset] the local time when this transition causes
75
+ # the next observance to start.
76
+ def local_start_at
77
+ TimestampWithOffset.new(@timestamp_value, 0, @offset.observed_utc_offset).set_timezone_offset(@offset)
94
78
  end
95
-
96
- # Returns true if this TimezoneTransition is equal to the given
97
- # TimezoneTransition. Two TimezoneTransition instances are
98
- # considered to be equal by == if offset, previous_offset and at are all
99
- # equal.
79
+
80
+ # Determines if this {TimezoneTransition} is equal to another instance.
81
+ #
82
+ # @param tti [Object] the instance to test for equality.
83
+ # @return [Boolean] `true` if `tti` is a {TimezoneTransition} with the same
84
+ # {offset}, {previous_offset} and {timestamp_value} as this
85
+ # {TimezoneTransition}, otherwise `false`.
100
86
  def ==(tti)
101
87
  tti.kind_of?(TimezoneTransition) &&
102
- offset == tti.offset && previous_offset == tti.previous_offset && at == tti.at
103
- end
104
-
105
- # Returns true if this TimezoneTransition is equal to the given
106
- # TimezoneTransition. Two TimezoneTransition instances are
107
- # considered to be equal by eql? if offset, previous_offset and at are all
108
- # equal and the type used to define at in both instances is the same.
109
- def eql?(tti)
110
- tti.kind_of?(TimezoneTransition) &&
111
- offset == tti.offset && previous_offset == tti.previous_offset && at.eql?(tti.at)
112
- end
113
-
114
- # Returns a hash of this TimezoneTransition instance.
115
- def hash
116
- @offset.hash ^ @previous_offset.hash ^ at.hash
117
- end
118
-
119
- # Returns internal object state as a programmer-readable string.
120
- def inspect
121
- "#<#{self.class}: #{at.inspect},#{@offset.inspect}>"
88
+ offset == tti.offset && previous_offset == tti.previous_offset && timestamp_value == tti.timestamp_value
122
89
  end
90
+ alias eql? ==
123
91
 
124
- private
125
-
126
- def raise_not_implemented(method_name)
127
- raise NotImplementedError, "Subclasses must override #{method_name}"
92
+ # @return [Integer] a hash based on {offset}, {previous_offset} and
93
+ # {timestamp_value}.
94
+ def hash
95
+ [@offset, @previous_offset, @timestamp_value].hash
128
96
  end
129
97
  end
130
98
  end
@@ -0,0 +1,63 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ # Represents a period of time in a time zone where the same offset from UTC
6
+ # applies. The period of time is bounded at at least one end, either having a
7
+ # start transition, end transition or both start and end transitions.
8
+ class TransitionsTimezonePeriod < TimezonePeriod
9
+ # @return [TimezoneTransition] the transition that defines the start of this
10
+ # {TimezonePeriod} (`nil` if the start is unbounded).
11
+ attr_reader :start_transition
12
+
13
+ # @return [TimezoneTransition] the transition that defines the end of this
14
+ # {TimezonePeriod} (`nil` if the end is unbounded).
15
+ attr_reader :end_transition
16
+
17
+ # Initializes a {TransitionsTimezonePeriod}.
18
+ #
19
+ # At least one of `start_transition` and `end_transition` must be specified.
20
+ #
21
+ # @param start_transition [TimezoneTransition] the transition that defines
22
+ # the start of the period, or `nil` if the start is unbounded.
23
+ # @param end_transition [TimezoneTransition] the transition that defines the
24
+ # end of the period, or `nil` if the end is unbounded.
25
+ # @raise [ArgumentError] if both `start_transition` and `end_transition` are
26
+ # `nil`.
27
+ def initialize(start_transition, end_transition)
28
+ if start_transition
29
+ super(start_transition.offset)
30
+ elsif end_transition
31
+ super(end_transition.previous_offset)
32
+ else
33
+ raise ArgumentError, 'At least one of start_transition and end_transition must be specified'
34
+ end
35
+
36
+ @start_transition = start_transition
37
+ @end_transition = end_transition
38
+ end
39
+
40
+ # Determines if this {TransitionsTimezonePeriod} is equal to another
41
+ # instance.
42
+ #
43
+ # @param p [Object] the instance to test for equality.
44
+ # @return [Boolean] `true` if `p` is a {TransitionsTimezonePeriod} with the
45
+ # same {offset}, {start_transition} and {end_transition}, otherwise
46
+ # `false`.
47
+ def ==(p)
48
+ p.kind_of?(TransitionsTimezonePeriod) && start_transition == p.start_transition && end_transition == p.end_transition
49
+ end
50
+ alias eql? ==
51
+
52
+ # @return [Integer] a hash based on {start_transition} and {end_transition}.
53
+ def hash
54
+ [@start_transition, @end_transition].hash
55
+ end
56
+
57
+ # @return [String] the internal object state as a programmer-readable
58
+ # `String`.
59
+ def inspect
60
+ "#<#{self.class}: @start_transition=#{@start_transition.inspect}, @end_transition=#{@end_transition.inspect}>"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ # Object#untaint is deprecated in Ruby >= 2.7 and will be removed in 3.2.
6
+ # UntaintExt adds a refinement to make Object#untaint a no-op and avoid the
7
+ # warning.
8
+ #
9
+ # @private
10
+ module UntaintExt # :nodoc:
11
+ refine Object do
12
+ def untaint
13
+ self
14
+ end
15
+ end
16
+ end
17
+ private_constant :UntaintExt
18
+ end