tzinfo 1.2.11 → 2.0.0

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 (151) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.yardopts +3 -0
  4. data/CHANGES.md +469 -431
  5. data/LICENSE +13 -13
  6. data/README.md +368 -114
  7. data/lib/tzinfo/country.rb +131 -129
  8. data/lib/tzinfo/country_timezone.rb +70 -112
  9. data/lib/tzinfo/data_source.rb +389 -144
  10. data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
  11. data/lib/tzinfo/data_sources/country_info.rb +42 -0
  12. data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
  13. data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
  14. data/lib/tzinfo/data_sources/ruby_data_source.rb +141 -0
  15. data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
  16. data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
  17. data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +573 -0
  18. data/lib/tzinfo/data_sources/zoneinfo_reader.rb +284 -0
  19. data/lib/tzinfo/data_sources.rb +8 -0
  20. data/lib/tzinfo/data_timezone.rb +33 -47
  21. data/lib/tzinfo/datetime_with_offset.rb +153 -0
  22. data/lib/tzinfo/format1/country_definer.rb +17 -0
  23. data/lib/tzinfo/format1/country_index_definition.rb +64 -0
  24. data/lib/tzinfo/format1/timezone_definer.rb +64 -0
  25. data/lib/tzinfo/format1/timezone_definition.rb +39 -0
  26. data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
  27. data/lib/tzinfo/format1.rb +10 -0
  28. data/lib/tzinfo/format2/country_definer.rb +68 -0
  29. data/lib/tzinfo/format2/country_index_definer.rb +68 -0
  30. data/lib/tzinfo/format2/country_index_definition.rb +46 -0
  31. data/lib/tzinfo/format2/timezone_definer.rb +94 -0
  32. data/lib/tzinfo/format2/timezone_definition.rb +73 -0
  33. data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
  34. data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
  35. data/lib/tzinfo/format2.rb +10 -0
  36. data/lib/tzinfo/info_timezone.rb +26 -21
  37. data/lib/tzinfo/linked_timezone.rb +33 -52
  38. data/lib/tzinfo/offset_timezone_period.rb +42 -0
  39. data/lib/tzinfo/string_deduper.rb +118 -0
  40. data/lib/tzinfo/time_with_offset.rb +128 -0
  41. data/lib/tzinfo/timestamp.rb +548 -0
  42. data/lib/tzinfo/timestamp_with_offset.rb +85 -0
  43. data/lib/tzinfo/timezone.rb +979 -502
  44. data/lib/tzinfo/timezone_offset.rb +84 -74
  45. data/lib/tzinfo/timezone_period.rb +151 -217
  46. data/lib/tzinfo/timezone_proxy.rb +70 -79
  47. data/lib/tzinfo/timezone_transition.rb +77 -109
  48. data/lib/tzinfo/transitions_timezone_period.rb +63 -0
  49. data/lib/tzinfo/version.rb +7 -0
  50. data/lib/tzinfo/with_offset.rb +61 -0
  51. data/lib/tzinfo.rb +60 -40
  52. data.tar.gz.sig +0 -0
  53. metadata +51 -115
  54. metadata.gz.sig +2 -3
  55. data/Rakefile +0 -107
  56. data/lib/tzinfo/annual_rules.rb +0 -51
  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/posix_time_zone_parser.rb +0 -136
  63. data/lib/tzinfo/ruby_core_support.rb +0 -176
  64. data/lib/tzinfo/ruby_country_info.rb +0 -74
  65. data/lib/tzinfo/ruby_data_source.rb +0 -136
  66. data/lib/tzinfo/time_or_datetime.rb +0 -351
  67. data/lib/tzinfo/timezone_definition.rb +0 -36
  68. data/lib/tzinfo/timezone_index_definition.rb +0 -54
  69. data/lib/tzinfo/timezone_info.rb +0 -30
  70. data/lib/tzinfo/timezone_transition_definition.rb +0 -104
  71. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  72. data/lib/tzinfo/transition_rule.rb +0 -325
  73. data/lib/tzinfo/zoneinfo_country_info.rb +0 -37
  74. data/lib/tzinfo/zoneinfo_data_source.rb +0 -504
  75. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -516
  76. data/test/assets/payload.rb +0 -1
  77. data/test/tc_annual_rules.rb +0 -95
  78. data/test/tc_country.rb +0 -240
  79. data/test/tc_country_index_definition.rb +0 -69
  80. data/test/tc_country_info.rb +0 -16
  81. data/test/tc_country_timezone.rb +0 -173
  82. data/test/tc_data_source.rb +0 -218
  83. data/test/tc_data_timezone.rb +0 -99
  84. data/test/tc_data_timezone_info.rb +0 -18
  85. data/test/tc_info_timezone.rb +0 -34
  86. data/test/tc_linked_timezone.rb +0 -155
  87. data/test/tc_linked_timezone_info.rb +0 -23
  88. data/test/tc_offset_rationals.rb +0 -23
  89. data/test/tc_posix_time_zone_parser.rb +0 -261
  90. data/test/tc_ruby_core_support.rb +0 -168
  91. data/test/tc_ruby_country_info.rb +0 -110
  92. data/test/tc_ruby_data_source.rb +0 -175
  93. data/test/tc_time_or_datetime.rb +0 -674
  94. data/test/tc_timezone.rb +0 -1361
  95. data/test/tc_timezone_definition.rb +0 -113
  96. data/test/tc_timezone_index_definition.rb +0 -73
  97. data/test/tc_timezone_info.rb +0 -11
  98. data/test/tc_timezone_london.rb +0 -143
  99. data/test/tc_timezone_melbourne.rb +0 -142
  100. data/test/tc_timezone_new_york.rb +0 -142
  101. data/test/tc_timezone_offset.rb +0 -126
  102. data/test/tc_timezone_period.rb +0 -555
  103. data/test/tc_timezone_proxy.rb +0 -136
  104. data/test/tc_timezone_transition.rb +0 -366
  105. data/test/tc_timezone_transition_definition.rb +0 -295
  106. data/test/tc_timezone_utc.rb +0 -27
  107. data/test/tc_transition_data_timezone_info.rb +0 -433
  108. data/test/tc_transition_rule.rb +0 -663
  109. data/test/tc_zoneinfo_country_info.rb +0 -78
  110. data/test/tc_zoneinfo_data_source.rb +0 -1226
  111. data/test/tc_zoneinfo_timezone_info.rb +0 -2149
  112. data/test/test_utils.rb +0 -214
  113. data/test/ts_all.rb +0 -7
  114. data/test/ts_all_ruby.rb +0 -5
  115. data/test/ts_all_zoneinfo.rb +0 -9
  116. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
  117. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -327
  118. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -230
  119. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
  120. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
  121. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
  122. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
  123. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -273
  124. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -198
  125. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -333
  126. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -277
  127. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -235
  128. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
  129. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -940
  130. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -609
  131. data/test/tzinfo-data/tzinfo/data/version.rb +0 -20
  132. data/test/tzinfo-data/tzinfo/data.rb +0 -8
  133. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  134. data/test/zoneinfo/America/New_York +0 -0
  135. data/test/zoneinfo/Australia/Melbourne +0 -0
  136. data/test/zoneinfo/EST +0 -0
  137. data/test/zoneinfo/Etc/UTC +0 -0
  138. data/test/zoneinfo/Europe/Amsterdam +0 -0
  139. data/test/zoneinfo/Europe/Andorra +0 -0
  140. data/test/zoneinfo/Europe/London +0 -0
  141. data/test/zoneinfo/Europe/Paris +0 -0
  142. data/test/zoneinfo/Europe/Prague +0 -0
  143. data/test/zoneinfo/Factory +0 -0
  144. data/test/zoneinfo/iso3166.tab +0 -274
  145. data/test/zoneinfo/leapseconds +0 -78
  146. data/test/zoneinfo/posix/Europe/London +0 -0
  147. data/test/zoneinfo/posixrules +0 -0
  148. data/test/zoneinfo/right/Europe/London +0 -0
  149. data/test/zoneinfo/zone.tab +0 -452
  150. data/test/zoneinfo/zone1970.tab +0 -384
  151. data/tzinfo.gemspec +0 -21
@@ -1,104 +1,102 @@
1
- require 'thread_safe'
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module TZInfo
4
- # Raised by Country#get if the code given is not valid.
5
+ # {InvalidCountryCode} is raised by {Country#get} if the code given is not a
6
+ # valid ISO 3166-1 alpha-2 code.
5
7
  class InvalidCountryCode < StandardError
6
8
  end
7
-
8
- # The Country class represents an ISO 3166-1 country. It can be used to
9
- # obtain a list of Timezones for a country. For example:
9
+
10
+ # The {Country} class represents an ISO 3166-1 country. It can be used to
11
+ # obtain a list of time zones observed by a country. For example:
10
12
  #
11
- # us = Country.get('US')
12
- # us.zone_identifiers
13
- # us.zones
14
- # us.zone_info
13
+ # united_states = Country.get('US')
14
+ # united_states.zone_identifiers
15
+ # united_states.zones
16
+ # united_states.zone_info
15
17
  #
16
- # The Country class is thread-safe. It is safe to use class and instance
17
- # methods of Country in concurrently executing threads. Instances of Country
18
- # can be shared across thread boundaries.
18
+ # The {Country} class is thread-safe. It is safe to use class and instance
19
+ # methods of {Country} in concurrently executing threads. Instances of
20
+ # {Country} can be shared across thread boundaries.
19
21
  #
20
- # Country information available through TZInfo is intended as an aid for
21
- # users, to help them select time zone data appropriate for their practical
22
- # needs. It is not intended to take or endorse any position on legal or
22
+ # Country information available through TZInfo is intended as an aid for
23
+ # users, to help them select time zone data appropriate for their practical
24
+ # needs. It is not intended to take or endorse any position on legal or
23
25
  # territorial claims.
24
26
  class Country
25
27
  include Comparable
26
-
27
- # Defined countries.
28
- #
29
- # @!visibility private
30
- @@countries = nil
31
-
32
- # Whether the countries index has been loaded yet.
33
- #
34
- # @!visibility private
35
- @@index_loaded = false
36
-
37
- # Gets a Country by its ISO 3166-1 alpha-2 code. Raises an
38
- # InvalidCountryCode exception if it couldn't be found.
39
- def self.get(identifier)
40
- instance = @@countries[identifier]
41
-
42
- unless instance
43
- # Thread-safety: It is possible that multiple equivalent Country
44
- # instances could be created here in concurrently executing threads.
45
- # The consequences of this are that the data may be loaded more than
46
- # once (depending on the data source) and memoized calculations could
47
- # be discarded. The performance benefit of ensuring that only a single
48
- # instance is created is unlikely to be worth the overhead of only
49
- # allowing one Country to be loaded at a time.
50
- info = data_source.load_country_info(identifier)
51
- instance = Country.new(info)
52
- @@countries[identifier] = instance
53
- end
54
-
55
- instance
56
- end
57
-
58
- # If identifier is a CountryInfo object, initializes the Country instance,
59
- # otherwise calls get(identifier).
60
- def self.new(identifier)
61
- if identifier.kind_of?(CountryInfo)
62
- instance = super()
63
- instance.send :setup, identifier
64
- instance
65
- else
66
- get(identifier)
28
+
29
+ class << self
30
+ # Gets a {Country} by its ISO 3166-1 alpha-2 code.
31
+ #
32
+ # The {Country.all_codes} method can be used to obtain a list of valid ISO
33
+ # 3166-1 alpha-2 codes.
34
+ #
35
+ # @param code [String] An ISO 3166-1 alpha-2 code.
36
+ # @return [Country] a {Country} instance representing the ISO-3166-1
37
+ # country identified by the `code` parameter.
38
+ # @raise [InvalidCountryCode] If {code} is not a valid ISO 3166-1 alpha-2
39
+ # code it couldn't be found.
40
+ def get(code)
41
+ Country.new(data_source.get_country_info(code))
42
+ end
43
+
44
+ # @return [Array<String>] an `Array` containing all the valid ISO 3166-1
45
+ # alpha-2 country codes.
46
+ def all_codes
47
+ data_source.country_codes
48
+ end
49
+
50
+ # @return [Array<Country>] an `Array` containing one {Country} instance
51
+ # for each defined country.
52
+ def all
53
+ data_source.country_codes.collect {|code| get(code)}
54
+ end
55
+
56
+ private
57
+
58
+ # @return [DataSource] the current DataSource.
59
+ def data_source
60
+ DataSource.get
67
61
  end
68
62
  end
69
-
70
- # Returns an Array of all the valid country codes.
71
- def self.all_codes
72
- data_source.country_codes
63
+
64
+ # Initializes a new {Country} based upon a {DataSources::CountryInfo}
65
+ # instance.
66
+ #
67
+ # {Country} instances should not normally be constructed directly. Use
68
+ # the {Country.get} method to obtain instances instead.
69
+ #
70
+ # @param info [DataSources::CountryInfo] the data to base the new {Country}
71
+ # instance upon.
72
+ def initialize(info)
73
+ @info = info
73
74
  end
74
-
75
- # Returns an Array of all the defined Countries.
76
- def self.all
77
- data_source.country_codes.collect {|code| get(code)}
78
- end
79
-
80
- # The ISO 3166-1 alpha-2 country code.
75
+
76
+ # @return [String] the ISO 3166-1 alpha-2 country code.
81
77
  def code
82
78
  @info.code
83
79
  end
84
-
85
- # The name of the country.
80
+
81
+ # @return [String] the name of the country.
86
82
  def name
87
83
  @info.name
88
84
  end
89
-
90
- # Alias for name.
85
+
86
+ # @return [String] a `String` representation of this {Country} (the name of
87
+ # the country).
91
88
  def to_s
92
89
  name
93
90
  end
94
-
95
- # Returns internal object state as a programmer-readable string.
91
+
92
+ # @return [String] the internal object state as a programmer-readable
93
+ # `String`.
96
94
  def inspect
97
95
  "#<#{self.class}: #{@info.code}>"
98
96
  end
99
-
100
- # Returns a frozen array of all the zone identifiers for the country. These
101
- # are in an order that
97
+
98
+ # Returns an `Array` containing the identifier for each time zone observed
99
+ # by the country. These are in an order that
102
100
  #
103
101
  # 1. makes some geographical sense, and
104
102
  # 2. puts the most populous zones first, where that does not contradict 1.
@@ -107,90 +105,94 @@ module TZInfo
107
105
  # country. This will occur if the zone covers multiple countries. Any zones
108
106
  # referring to a city or region in a different country will be listed after
109
107
  # those relating to this country.
108
+ #
109
+ # @return [Array<String>] an `Array` containing the identifier for each time
110
+ # zone observed by the country
110
111
  def zone_identifiers
111
- @info.zone_identifiers
112
+ zone_info.map(&:identifier)
112
113
  end
113
114
  alias zone_names zone_identifiers
114
-
115
- # An array of all the Timezones for this country. Returns TimezoneProxy
116
- # objects to avoid the overhead of loading Timezone definitions until
117
- # a conversion is actually required. The Timezones are returned in an order
118
- # that
115
+
116
+ # Returns An `Array` containing a {Timezone} instance for each time zone
117
+ # observed by the country. These are in an order that
119
118
  #
120
119
  # 1. makes some geographical sense, and
121
120
  # 2. puts the most populous zones first, where that does not contradict 1.
122
121
  #
123
- # Identifiers of the zones returned may refer to cities and regions outside
124
- # of the country. This will occur if the zone covers multiple countries. Any
125
- # zones referring to a city or region in a different country will be listed
126
- # after those relating to this country.
122
+ # The identifiers of the time zones returned may refer to cities and regions
123
+ # outside of the country. This will occur if the time zone covers multiple
124
+ # countries. Any zones referring to a city or region in a different country
125
+ # will be listed after those relating to this country.
126
+ #
127
+ # The results are actually instances of {TimezoneProxy} in order to defer
128
+ # loading of the time zone transition data until it is first needed.
129
+ #
130
+ # @return [Array<Timezone>] an `Array` containing a {Timezone} instance for
131
+ # each time zone observed by the country.
127
132
  def zones
128
- zone_identifiers.collect {|id|
129
- Timezone.get_proxy(id)
130
- }
133
+ zone_info.map(&:timezone)
131
134
  end
132
-
133
- # Returns a frozen array of all the timezones for the for the country as
134
- # CountryTimezone instances (containing extra information about each zone).
135
- # These are in an order that
135
+
136
+ # Returns a frozen `Array` containing a {CountryTimezone} instance for each
137
+ # time zone observed by the country. These are in an order that
136
138
  #
137
139
  # 1. makes some geographical sense, and
138
140
  # 2. puts the most populous zones first, where that does not contradict 1.
139
141
  #
140
- # Identifiers and descriptions of the zones returned may refer to cities and
141
- # regions outside of the country. This will occur if the zone covers
142
- # multiple countries. Any zones referring to a city or region in a different
143
- # country will be listed after those relating to this country.
142
+ # The {CountryTimezone} instances can be used to obtain the location and
143
+ # descriptions of the observed time zones.
144
+ #
145
+ # Identifiers and descriptions of the time zones returned may refer to
146
+ # cities and regions outside of the country. This will occur if the time
147
+ # zone covers multiple countries. Any zones referring to a city or region in
148
+ # a different country will be listed after those relating to this country.
149
+ #
150
+ # @return [Array<CountryTimezone>] a frozen `Array` containing a
151
+ # {CountryTimezone} instance for each time zone observed by the country.
144
152
  def zone_info
145
153
  @info.zones
146
154
  end
147
-
148
- # Compare two Countries based on their code. Returns -1 if c is less
149
- # than self, 0 if c is equal to self and +1 if c is greater than self.
155
+
156
+ # Compares this {Country} with another based on their {code}.
150
157
  #
151
- # Returns nil if c is not comparable with Country instances.
158
+ # @param c [Object] an `Object` to compare this {Country} with.
159
+ # @return [Integer] -1 if `c` is less than `self`, 0 if `c` is equal to
160
+ # `self` and +1 if `c` is greater than `self`, or `nil` if `c` is not an
161
+ # instance of {Country}.
152
162
  def <=>(c)
153
163
  return nil unless c.is_a?(Country)
154
164
  code <=> c.code
155
165
  end
156
-
157
- # Returns true if and only if the code of c is equal to the code of this
158
- # Country.
166
+
167
+ # @param c [Object] an `Object` to compare this {Country} with.
168
+ # @return [Boolean] `true` if `c` is an instance of {Country} and has the
169
+ # same code as `self`, otherwise `false`.
159
170
  def eql?(c)
160
171
  self == c
161
172
  end
162
-
163
- # Returns a hash value for this Country.
173
+
174
+ # @return [Integer] a hash based on the {code}.
164
175
  def hash
165
176
  code.hash
166
177
  end
167
-
168
- # Dumps this Country for marshalling.
178
+
179
+ # Returns a serialized representation of this {Country}. This method is
180
+ # called when using `Marshal.dump` with an instance of {Country}.
181
+ #
182
+ # @param limit [Integer] the maximum depth to dump - ignored.
183
+ # @return [String] a serialized representation of this {Country}.
169
184
  def _dump(limit)
170
185
  code
171
186
  end
172
-
173
- # Loads a marshalled Country.
187
+
188
+ # Loads a {Country} from the serialized representation returned by {_dump}.
189
+ # This is method is called when using `Marshal.load` or `Marshal.restore`
190
+ # to restore a serialized {Country}.
191
+ #
192
+ # @param data [String] a serialized representation of a {Country}.
193
+ # @return [Country] the result of converting `data` back into a {Country}.
174
194
  def self._load(data)
175
195
  Country.get(data)
176
196
  end
177
-
178
- private
179
- # Called by Country.new to initialize a new Country instance. The info
180
- # parameter is a CountryInfo that defines the country.
181
- def setup(info)
182
- @info = info
183
- end
184
-
185
- # Initializes @@countries.
186
- def self.init_countries
187
- @@countries = ThreadSafe::Cache.new
188
- end
189
- init_countries
190
-
191
- # Returns the current DataSource
192
- def self.data_source
193
- DataSource.get
194
- end
195
- end
197
+ end
196
198
  end
@@ -1,135 +1,93 @@
1
+ # encoding: UTF-8
2
+
1
3
  module TZInfo
2
- # A Timezone within a Country. This contains extra information about the
3
- # Timezone that is specific to the Country (a Timezone could be used by
4
- # multiple countries).
4
+ # Information about a time zone used by a {Country}.
5
5
  class CountryTimezone
6
- # The zone identifier.
7
- attr_reader :identifier
8
-
9
- # A description of this timezone in relation to the country, e.g.
10
- # "Eastern Time". This is usually nil for countries having only a single
11
- # Timezone.
6
+ # @return [String] the identifier of the {Timezone} being described.
7
+ attr_reader :identifier
8
+
9
+ # The latitude of this time zone in degrees. Positive numbers are degrees
10
+ # north and negative numbers are degrees south.
11
+ #
12
+ # Note that depending on the data source, the position given by {#latitude}
13
+ # and {#longitude} may not be within the country.
14
+ #
15
+ # @return [Rational] the latitude in degrees.
16
+ attr_reader :latitude
17
+
18
+ # The longitude of this time zone in degrees. Positive numbers are degrees
19
+ # east and negative numbers are degrees west.
20
+ #
21
+ # Note that depending on the data source, the position given by {#latitude}
22
+ # and {#longitude} may not be within the country.
23
+ #
24
+ # @return [Rational] the longitude in degrees.
25
+ attr_reader :longitude
26
+
27
+ # A description of this time zone in relation to the country, e.g. "Eastern
28
+ # Time". This is usually `nil` for countries that have a single time zone.
29
+ #
30
+ # @return [String] an optional description of the time zone.
12
31
  attr_reader :description
13
-
14
- class << self
15
- # Creates a new CountryTimezone with a timezone identifier, latitude,
16
- # longitude and description. The latitude and longitude are specified as
17
- # rationals - a numerator and denominator. For performance reasons, the
18
- # numerators and denominators must be specified in their lowest form.
19
- #
20
- # For use internally within TZInfo.
21
- #
22
- # @!visibility private
23
- alias :new! :new
24
-
25
- # Creates a new CountryTimezone with a timezone identifier, latitude,
26
- # longitude and description. The latitude and longitude must be specified
27
- # as instances of Rational.
28
- #
29
- # CountryTimezone instances should normally only be constructed when
30
- # creating new DataSource implementations.
31
- def new(identifier, latitude, longitude, description = nil)
32
- super(identifier, latitude, nil, longitude, nil, description)
33
- end
34
- end
35
-
36
- # Creates a new CountryTimezone with a timezone identifier, latitude,
37
- # longitude and description. The latitude and longitude are specified as
38
- # rationals - a numerator and denominator. For performance reasons, the
39
- # numerators and denominators must be specified in their lowest form.
32
+
33
+ # Creates a new {CountryTimezone}.
34
+ #
35
+ # The passed in identifier and description instances will be frozen.
36
+ #
37
+ # {CountryTimezone} instances should normally only be constructed
38
+ # by implementations of {DataSource}.
40
39
  #
41
- # @!visibility private
42
- def initialize(identifier, latitude_numerator, latitude_denominator,
43
- longitude_numerator, longitude_denominator, description = nil) #:nodoc:
44
- @identifier = identifier
45
-
46
- if latitude_numerator.kind_of?(Rational)
47
- @latitude = latitude_numerator
48
- else
49
- @latitude = nil
50
- @latitude_numerator = latitude_numerator
51
- @latitude_denominator = latitude_denominator
52
- end
53
-
54
- if longitude_numerator.kind_of?(Rational)
55
- @longitude = longitude_numerator
56
- else
57
- @longitude = nil
58
- @longitude_numerator = longitude_numerator
59
- @longitude_denominator = longitude_denominator
60
- end
61
-
62
- @description = description
40
+ # @param identifier [String] the {Timezone} identifier.
41
+ # @param latitude [Rational] the latitude of the time zone.
42
+ # @param longitude [Rational] the longitude of the time zone.
43
+ # @param description [String] an optional description of the time zone.
44
+ def initialize(identifier, latitude, longitude, description = nil)
45
+ @identifier = identifier.freeze
46
+ @latitude = latitude
47
+ @longitude = longitude
48
+ @description = description && description.freeze
63
49
  end
64
-
65
- # The Timezone (actually a TimezoneProxy for performance reasons).
50
+
51
+ # Returns the associated {Timezone}.
52
+ #
53
+ # The result is actually an instance of {TimezoneProxy} in order to defer
54
+ # loading of the time zone transition data until it is first needed.
55
+ #
56
+ # @return [Timezone] the associated {Timezone}.
66
57
  def timezone
67
58
  Timezone.get_proxy(@identifier)
68
59
  end
69
-
70
- # if description is not nil, this method returns description; otherwise it
71
- # returns timezone.friendly_identifier(true).
60
+
61
+ # @return [String] the {description} if present, otherwise a human-readable
62
+ # representation of the identifier (using {Timezone#friendly_identifier}).
72
63
  def description_or_friendly_identifier
73
64
  description || timezone.friendly_identifier(true)
74
65
  end
75
-
76
- # The latitude of this timezone in degrees as a Rational.
77
- def latitude
78
- # Thread-safety: It is possible that the value of @latitude may be
79
- # calculated multiple times in concurrently executing threads. It is not
80
- # worth the overhead of locking to ensure that @latitude is only
81
- # calculated once.
82
- unless @latitude
83
- result = RubyCoreSupport.rational_new!(@latitude_numerator, @latitude_denominator)
84
- return result if frozen?
85
- @latitude = result
86
- end
87
-
88
- @latitude
89
- end
90
-
91
- # The longitude of this timezone in degrees as a Rational.
92
- def longitude
93
- # Thread-safety: It is possible that the value of @longitude may be
94
- # calculated multiple times in concurrently executing threads. It is not
95
- # worth the overhead of locking to ensure that @longitude is only
96
- # calculated once.
97
- unless @longitude
98
- result = RubyCoreSupport.rational_new!(@longitude_numerator, @longitude_denominator)
99
- return result if frozen?
100
- @longitude = result
101
- end
102
66
 
103
- @longitude
104
- end
105
-
106
- # Returns true if and only if the given CountryTimezone is equal to the
107
- # current CountryTimezone (has the same identifer, latitude, longitude
108
- # and description).
67
+ # Tests if the given object is equal to the current instance (has the same
68
+ # identifier, latitude, longitude and description).
69
+ #
70
+ # @param ct [Object] the object to be compared.
71
+ # @return [TrueClass] `true` if `ct` is equal to the current instance.
109
72
  def ==(ct)
110
73
  ct.kind_of?(CountryTimezone) &&
111
74
  identifier == ct.identifier && latitude == ct.latitude &&
112
- longitude == ct.longitude && description == ct.description
75
+ longitude == ct.longitude && description == ct.description
113
76
  end
114
-
115
- # Returns true if and only if the given CountryTimezone is equal to the
116
- # current CountryTimezone (has the same identifer, latitude, longitude
117
- # and description).
77
+
78
+ # Tests if the given object is equal to the current instance (has the same
79
+ # identifier, latitude, longitude and description).
80
+ #
81
+ # @param ct [Object] the object to be compared.
82
+ # @return [Boolean] `true` if `ct` is equal to the current instance.
118
83
  def eql?(ct)
119
84
  self == ct
120
85
  end
121
-
122
- # Returns a hash of this CountryTimezone.
86
+
87
+ # @return [Integer] a hash based on the {identifier}, {latitude},
88
+ # {longitude} and {description}.
123
89
  def hash
124
- @identifier.hash ^
125
- (@latitude ? @latitude.numerator.hash ^ @latitude.denominator.hash : @latitude_numerator.hash ^ @latitude_denominator.hash) ^
126
- (@longitude ? @longitude.numerator.hash ^ @longitude.denominator.hash : @longitude_numerator.hash ^ @longitude_denominator.hash) ^
127
- @description.hash
128
- end
129
-
130
- # Returns internal object state as a programmer-readable string.
131
- def inspect
132
- "#<#{self.class}: #@identifier>"
90
+ [@identifier, @latitude, @longitude, @description].hash
133
91
  end
134
92
  end
135
93
  end