tzinfo 1.2.11 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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