tzinfo 1.2.5

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.

Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +3 -0
  3. data.tar.gz.sig +0 -0
  4. data/.yardopts +6 -0
  5. data/CHANGES.md +786 -0
  6. data/LICENSE +19 -0
  7. data/README.md +151 -0
  8. data/Rakefile +107 -0
  9. data/lib/tzinfo.rb +40 -0
  10. data/lib/tzinfo/country.rb +196 -0
  11. data/lib/tzinfo/country_index_definition.rb +31 -0
  12. data/lib/tzinfo/country_info.rb +42 -0
  13. data/lib/tzinfo/country_timezone.rb +135 -0
  14. data/lib/tzinfo/data_source.rb +190 -0
  15. data/lib/tzinfo/data_timezone.rb +58 -0
  16. data/lib/tzinfo/data_timezone_info.rb +55 -0
  17. data/lib/tzinfo/info_timezone.rb +30 -0
  18. data/lib/tzinfo/linked_timezone.rb +63 -0
  19. data/lib/tzinfo/linked_timezone_info.rb +26 -0
  20. data/lib/tzinfo/offset_rationals.rb +77 -0
  21. data/lib/tzinfo/ruby_core_support.rb +146 -0
  22. data/lib/tzinfo/ruby_country_info.rb +74 -0
  23. data/lib/tzinfo/ruby_data_source.rb +136 -0
  24. data/lib/tzinfo/time_or_datetime.rb +340 -0
  25. data/lib/tzinfo/timezone.rb +669 -0
  26. data/lib/tzinfo/timezone_definition.rb +36 -0
  27. data/lib/tzinfo/timezone_index_definition.rb +54 -0
  28. data/lib/tzinfo/timezone_info.rb +30 -0
  29. data/lib/tzinfo/timezone_offset.rb +101 -0
  30. data/lib/tzinfo/timezone_period.rb +245 -0
  31. data/lib/tzinfo/timezone_proxy.rb +105 -0
  32. data/lib/tzinfo/timezone_transition.rb +130 -0
  33. data/lib/tzinfo/timezone_transition_definition.rb +104 -0
  34. data/lib/tzinfo/transition_data_timezone_info.rb +274 -0
  35. data/lib/tzinfo/zoneinfo_country_info.rb +37 -0
  36. data/lib/tzinfo/zoneinfo_data_source.rb +488 -0
  37. data/lib/tzinfo/zoneinfo_timezone_info.rb +296 -0
  38. data/test/tc_country.rb +234 -0
  39. data/test/tc_country_index_definition.rb +69 -0
  40. data/test/tc_country_info.rb +16 -0
  41. data/test/tc_country_timezone.rb +173 -0
  42. data/test/tc_data_source.rb +218 -0
  43. data/test/tc_data_timezone.rb +99 -0
  44. data/test/tc_data_timezone_info.rb +18 -0
  45. data/test/tc_info_timezone.rb +34 -0
  46. data/test/tc_linked_timezone.rb +155 -0
  47. data/test/tc_linked_timezone_info.rb +23 -0
  48. data/test/tc_offset_rationals.rb +23 -0
  49. data/test/tc_ruby_core_support.rb +168 -0
  50. data/test/tc_ruby_country_info.rb +110 -0
  51. data/test/tc_ruby_data_source.rb +143 -0
  52. data/test/tc_time_or_datetime.rb +654 -0
  53. data/test/tc_timezone.rb +1350 -0
  54. data/test/tc_timezone_definition.rb +113 -0
  55. data/test/tc_timezone_index_definition.rb +73 -0
  56. data/test/tc_timezone_info.rb +11 -0
  57. data/test/tc_timezone_london.rb +143 -0
  58. data/test/tc_timezone_melbourne.rb +142 -0
  59. data/test/tc_timezone_new_york.rb +142 -0
  60. data/test/tc_timezone_offset.rb +126 -0
  61. data/test/tc_timezone_period.rb +555 -0
  62. data/test/tc_timezone_proxy.rb +136 -0
  63. data/test/tc_timezone_transition.rb +366 -0
  64. data/test/tc_timezone_transition_definition.rb +295 -0
  65. data/test/tc_timezone_utc.rb +27 -0
  66. data/test/tc_transition_data_timezone_info.rb +423 -0
  67. data/test/tc_zoneinfo_country_info.rb +78 -0
  68. data/test/tc_zoneinfo_data_source.rb +1195 -0
  69. data/test/tc_zoneinfo_timezone_info.rb +1232 -0
  70. data/test/test_utils.rb +163 -0
  71. data/test/ts_all.rb +7 -0
  72. data/test/ts_all_ruby.rb +5 -0
  73. data/test/ts_all_zoneinfo.rb +7 -0
  74. data/test/tzinfo-data/tzinfo/data.rb +8 -0
  75. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +89 -0
  76. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +315 -0
  77. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +218 -0
  78. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +19 -0
  79. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +21 -0
  80. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +21 -0
  81. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +21 -0
  82. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +261 -0
  83. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +186 -0
  84. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +321 -0
  85. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +265 -0
  86. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +220 -0
  87. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +16 -0
  88. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +927 -0
  89. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +596 -0
  90. data/test/tzinfo-data/tzinfo/data/version.rb +14 -0
  91. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  92. data/test/zoneinfo/America/New_York +0 -0
  93. data/test/zoneinfo/Australia/Melbourne +0 -0
  94. data/test/zoneinfo/EST +0 -0
  95. data/test/zoneinfo/Etc/UTC +0 -0
  96. data/test/zoneinfo/Europe/Amsterdam +0 -0
  97. data/test/zoneinfo/Europe/Andorra +0 -0
  98. data/test/zoneinfo/Europe/London +0 -0
  99. data/test/zoneinfo/Europe/Paris +0 -0
  100. data/test/zoneinfo/Europe/Prague +0 -0
  101. data/test/zoneinfo/Factory +0 -0
  102. data/test/zoneinfo/iso3166.tab +275 -0
  103. data/test/zoneinfo/leapseconds +61 -0
  104. data/test/zoneinfo/posix/Europe/London +0 -0
  105. data/test/zoneinfo/posixrules +0 -0
  106. data/test/zoneinfo/right/Europe/London +0 -0
  107. data/test/zoneinfo/zone.tab +439 -0
  108. data/test/zoneinfo/zone1970.tab +369 -0
  109. data/tzinfo.gemspec +21 -0
  110. metadata +193 -0
  111. metadata.gz.sig +2 -0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2005-2018 Philip Ross
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,151 @@
1
+ TZInfo - Ruby Timezone Library
2
+ ==============================
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/tzinfo.svg)](http://badge.fury.io/rb/tzinfo) [![Build Status](https://travis-ci.org/tzinfo/tzinfo.svg?branch=master)](https://travis-ci.org/tzinfo/tzinfo)
5
+
6
+ [TZInfo](http://tzinfo.github.io) provides daylight savings aware
7
+ transformations between times in different timezones.
8
+
9
+
10
+ Data Sources
11
+ ------------
12
+
13
+ TZInfo requires a source of timezone data. There are two built-in options:
14
+
15
+ 1. The TZInfo::Data library (the tzinfo-data gem). TZInfo::Data contains a set
16
+ of Ruby modules that are generated from the [IANA Time Zone Database](http://www.iana.org/time-zones).
17
+ 2. A zoneinfo directory. Most Unix-like systems include a zoneinfo directory
18
+ containing timezone definitions. These are also generated from the
19
+ [IANA Time Zone Database](http://www.iana.org/time-zones).
20
+
21
+ By default, TZInfo::Data will be used. If TZInfo::Data is not available (i.e.
22
+ if `require 'tzinfo/data'` fails), then TZInfo will search for a zoneinfo
23
+ directory instead (using the search path specified by
24
+ `TZInfo::ZoneinfoDataSource::DEFAULT_SEARCH_PATH`).
25
+
26
+ If no data source can be found, a `TZInfo::DataSourceNotFound` exception will be
27
+ raised when TZInfo is used. Further information is available
28
+ [in the wiki](http://tzinfo.github.io/datasourcenotfound) to help with
29
+ resolving `TZInfo::DataSourceNotFound` errors.
30
+
31
+ The default data source selection can be overridden using
32
+ `TZInfo::DataSource.set`.
33
+
34
+ Custom data sources can also be used. See `TZInfo::DataSource.set` for
35
+ further details.
36
+
37
+
38
+ Installation
39
+ ------------
40
+
41
+ The TZInfo gem can be installed by running:
42
+
43
+ gem install tzinfo
44
+
45
+ To use the Ruby modules as the data source, TZInfo::Data will also need to be
46
+ installed:
47
+
48
+ gem install tzinfo-data
49
+
50
+
51
+ Example Usage
52
+ -------------
53
+
54
+ The following code will obtain the America/New_York timezone (as an instance
55
+ of `TZInfo::Timezone`) and convert a time in UTC to local New York time:
56
+
57
+ require 'tzinfo'
58
+
59
+ tz = TZInfo::Timezone.get('America/New_York')
60
+ local = tz.utc_to_local(Time.utc(2005,8,29,15,35,0))
61
+
62
+ Note that the local Time returned will have a UTC timezone (`local.zone` will
63
+ return `"UTC"`). This is because the Ruby Time class only supports two timezones:
64
+ UTC and the current system local timezone.
65
+
66
+ To convert from a local time to UTC, the `local_to_utc` method can be used as
67
+ follows:
68
+
69
+ utc = tz.local_to_utc(local)
70
+
71
+ Note that the timezone information of the local Time object is ignored (TZInfo
72
+ will just read the date and time and treat them as if there were in the `tz`
73
+ timezone). The following two lines will return the same result regardless of
74
+ the system's local timezone:
75
+
76
+ tz.local_to_utc(Time.local(2006,6,26,1,0,0))
77
+ tz.local_to_utc(Time.utc(2006,6,26,1,0,0))
78
+
79
+ To obtain information about the rules in force at a particular UTC or local
80
+ time, the `TZInfo::Timezone.period_for_utc` and
81
+ `TZInfo::Timezone.period_for_local` methods can be used. Both of these methods
82
+ return `TZInfo::TimezonePeriod` objects. The following gets the identifier for
83
+ the period (in this case EDT).
84
+
85
+ period = tz.period_for_utc(Time.utc(2005,8,29,15,35,0))
86
+ id = period.zone_identifier
87
+
88
+ The current local time in a `Timezone` can be obtained with the
89
+ `TZInfo::Timezone#now` method:
90
+
91
+ now = tz.now
92
+
93
+ All methods in TZInfo that operate on a time can be used with either `Time` or
94
+ `DateTime` instances or with Integer timestamps (i.e. as returned by
95
+ `Time#to_i`). The type of the values returned will match the type passed in.
96
+
97
+ A list of all the available timezone identifiers can be obtained using the
98
+ `TZInfo::Timezone.all_identifiers` method. `TZInfo::Timezone.all` can be called
99
+ to get an `Array` of all the `TZInfo::Timezone` instances.
100
+
101
+ Timezones can also be accessed by country (using an ISO 3166-1 alpha-2 country
102
+ code). The following code retrieves the `TZInfo::Country` instance representing
103
+ the USA (country code 'US') and then gets all the timezone identifiers used in
104
+ the USA.
105
+
106
+ us = TZInfo::Country.get('US')
107
+ timezones = us.zone_identifiers
108
+
109
+ The `TZInfo::Country#zone_info` method provides an additional description and
110
+ geographic location for each timezone in a country.
111
+
112
+ A list of all the available country codes can be obtained using the
113
+ `TZInfo::Country.all_codes` method. `TZInfo::Country.all` can be called to get
114
+ an `Array` of all the `Country` instances.
115
+
116
+ For further detail, please refer to the API documentation for the
117
+ `TZInfo::Timezone` and `TZInfo::Country` classes.
118
+
119
+
120
+ Thread-Safety
121
+ -------------
122
+
123
+ The `TZInfo::Country` and `TZInfo::Timezone` classes are thread-safe. It is safe
124
+ to use class and instance methods of `TZInfo::Country` and `TZInfo::Timezone` in
125
+ concurrently executing threads. Instances of both classes can be shared across
126
+ thread boundaries.
127
+
128
+
129
+ Documentation
130
+ -------------
131
+
132
+ API documentation for TZInfo is available on [RubyDoc.info](http://rubydoc.info/gems/tzinfo/frames).
133
+
134
+
135
+ License
136
+ -------
137
+
138
+ TZInfo is released under the MIT license, see LICENSE for details.
139
+
140
+
141
+ Source Code
142
+ -----------
143
+
144
+ Source code for TZInfo is available on [GitHub](https://github.com/tzinfo/tzinfo).
145
+
146
+
147
+ Issue Tracker
148
+ -------------
149
+
150
+ Please post any bugs, issues, feature requests or questions to the
151
+ [GitHub issue tracker](https://github.com/tzinfo/tzinfo/issues).
@@ -0,0 +1,107 @@
1
+ require 'rubygems'
2
+ require 'rubygems/package_task'
3
+ require 'fileutils'
4
+ require 'rake/testtask'
5
+
6
+ # Ignore errors loading rdoc/task (the rdoc tasks will be excluded if
7
+ # rdoc is unavailable).
8
+ begin
9
+ require 'rdoc/task'
10
+ rescue LoadError, RuntimeError
11
+ end
12
+
13
+ BASE_DIR = File.expand_path(File.dirname(__FILE__))
14
+
15
+ task :default => [:test]
16
+
17
+ spec = eval(File.read('tzinfo.gemspec'))
18
+
19
+ class TZInfoPackageTask < Gem::PackageTask
20
+ alias_method :orig_sh, :sh
21
+ private :orig_sh
22
+
23
+ def sh(*cmd, &block)
24
+ if cmd[0] == '__tar_with_owner__' && cmd[1] =~ /\A-?[zjcvf]+\z/
25
+ opts = cmd[1]
26
+ cmd = ['tar', 'c', '--owner', '0', '--group', '0', "#{opts.start_with?('-') ? '' : '-'}#{opts.gsub('c', '')}"] + cmd.drop(2)
27
+ elsif cmd.first =~ /\A__tar_with_owner__ -?([zjcvf]+)(.*)\z/
28
+ opts = $1
29
+ args = $2
30
+ cmd[0] = "tar c --owner 0 --group 0 -#{opts.gsub('c', '')}#{args}"
31
+ end
32
+
33
+ orig_sh(*cmd, &block)
34
+ end
35
+ end
36
+
37
+ def add_signing_key(spec)
38
+ # Attempt to find the private key and add options to sign the gem if found.
39
+ private_key_path = File.expand_path(File.join(BASE_DIR, '..', 'key', 'gem-private_key.pem'))
40
+
41
+ if File.exist?(private_key_path)
42
+ spec = spec.clone
43
+ spec.signing_key = private_key_path
44
+ spec.cert_chain = [File.join(BASE_DIR, 'gem-public_cert.pem')]
45
+ else
46
+ puts 'WARNING: Private key not found. Not signing gem file.'
47
+ end
48
+
49
+ spec
50
+ end
51
+
52
+ package_task = TZInfoPackageTask.new(add_signing_key(spec)) do |pkg|
53
+ pkg.need_zip = true
54
+ pkg.need_tar_gz = true
55
+ pkg.tar_command = '__tar_with_owner__'
56
+ end
57
+
58
+ # Skip the rdoc task if RDoc::Task is unavailable
59
+ if defined?(RDoc) && defined?(RDoc::Task)
60
+ RDoc::Task.new do |rdoc|
61
+ rdoc.rdoc_dir = 'doc'
62
+ rdoc.options.concat spec.rdoc_options
63
+ rdoc.rdoc_files.include(spec.extra_rdoc_files)
64
+ rdoc.rdoc_files.include('lib')
65
+ end
66
+ end
67
+
68
+ Rake::Task[package_task.package_dir_path].enhance do
69
+ recurse_chmod(package_task.package_dir_path)
70
+ end
71
+
72
+ Rake::Task[:package].enhance do
73
+ FileUtils.rm_rf(package_task.package_dir_path)
74
+ end
75
+
76
+ def recurse_chmod(dir)
77
+ File.chmod(0755, dir)
78
+
79
+ Dir.entries(dir).each do |entry|
80
+ if entry != '.' && entry != '..'
81
+ path = File.join(dir, entry)
82
+ if File.directory?(path)
83
+ recurse_chmod(path)
84
+ else
85
+ File.chmod(0644, path)
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ desc 'Run tests using RubyDataSource, then ZoneinfoDataSource'
92
+ task :test => [:test_ruby, :test_zoneinfo] do
93
+ end
94
+
95
+ def setup_tests(test_task, type)
96
+ test_task.libs = [File.join(BASE_DIR, 'lib')]
97
+ test_task.pattern = File.join(BASE_DIR, 'test', "ts_all_#{type}.rb")
98
+ test_task.warning = true
99
+ end
100
+
101
+ Rake::TestTask.new(:test_ruby) do |t|
102
+ setup_tests(t, :ruby)
103
+ end
104
+
105
+ Rake::TestTask.new(:test_zoneinfo) do |t|
106
+ setup_tests(t, :zoneinfo)
107
+ end
@@ -0,0 +1,40 @@
1
+ # Top level module for TZInfo.
2
+ module TZInfo
3
+ end
4
+
5
+ require 'tzinfo/ruby_core_support'
6
+ require 'tzinfo/offset_rationals'
7
+ require 'tzinfo/time_or_datetime'
8
+
9
+ require 'tzinfo/timezone_definition'
10
+
11
+ require 'tzinfo/timezone_offset'
12
+ require 'tzinfo/timezone_transition'
13
+ require 'tzinfo/timezone_transition_definition'
14
+
15
+ require 'tzinfo/timezone_index_definition'
16
+
17
+ require 'tzinfo/timezone_info'
18
+ require 'tzinfo/data_timezone_info'
19
+ require 'tzinfo/linked_timezone_info'
20
+ require 'tzinfo/transition_data_timezone_info'
21
+ require 'tzinfo/zoneinfo_timezone_info'
22
+
23
+ require 'tzinfo/data_source'
24
+ require 'tzinfo/ruby_data_source'
25
+ require 'tzinfo/zoneinfo_data_source'
26
+
27
+ require 'tzinfo/timezone_period'
28
+ require 'tzinfo/timezone'
29
+ require 'tzinfo/info_timezone'
30
+ require 'tzinfo/data_timezone'
31
+ require 'tzinfo/linked_timezone'
32
+ require 'tzinfo/timezone_proxy'
33
+
34
+ require 'tzinfo/country_index_definition'
35
+ require 'tzinfo/country_info'
36
+ require 'tzinfo/ruby_country_info'
37
+ require 'tzinfo/zoneinfo_country_info'
38
+
39
+ require 'tzinfo/country'
40
+ require 'tzinfo/country_timezone'
@@ -0,0 +1,196 @@
1
+ require 'thread_safe'
2
+
3
+ module TZInfo
4
+ # Raised by Country#get if the code given is not valid.
5
+ class InvalidCountryCode < StandardError
6
+ 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:
10
+ #
11
+ # us = Country.get('US')
12
+ # us.zone_identifiers
13
+ # us.zones
14
+ # us.zone_info
15
+ #
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.
19
+ #
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
23
+ # territorial claims.
24
+ class Country
25
+ 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)
67
+ end
68
+ end
69
+
70
+ # Returns an Array of all the valid country codes.
71
+ def self.all_codes
72
+ data_source.country_codes
73
+ 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.
81
+ def code
82
+ @info.code
83
+ end
84
+
85
+ # The name of the country.
86
+ def name
87
+ @info.name
88
+ end
89
+
90
+ # Alias for name.
91
+ def to_s
92
+ name
93
+ end
94
+
95
+ # Returns internal object state as a programmer-readable string.
96
+ def inspect
97
+ "#<#{self.class}: #{@info.code}>"
98
+ end
99
+
100
+ # Returns a frozen array of all the zone identifiers for the country. These
101
+ # are in an order that
102
+ #
103
+ # 1. makes some geographical sense, and
104
+ # 2. puts the most populous zones first, where that does not contradict 1.
105
+ #
106
+ # Returned zone identifiers may refer to cities and regions outside of the
107
+ # country. This will occur if the zone covers multiple countries. Any zones
108
+ # referring to a city or region in a different country will be listed after
109
+ # those relating to this country.
110
+ def zone_identifiers
111
+ @info.zone_identifiers
112
+ end
113
+ 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
119
+ #
120
+ # 1. makes some geographical sense, and
121
+ # 2. puts the most populous zones first, where that does not contradict 1.
122
+ #
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.
127
+ def zones
128
+ zone_identifiers.collect {|id|
129
+ Timezone.get_proxy(id)
130
+ }
131
+ 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
136
+ #
137
+ # 1. makes some geographical sense, and
138
+ # 2. puts the most populous zones first, where that does not contradict 1.
139
+ #
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.
144
+ def zone_info
145
+ @info.zones
146
+ 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.
150
+ #
151
+ # Returns nil if c is not comparable with Country instances.
152
+ def <=>(c)
153
+ return nil unless c.is_a?(Country)
154
+ code <=> c.code
155
+ end
156
+
157
+ # Returns true if and only if the code of c is equal to the code of this
158
+ # Country.
159
+ def eql?(c)
160
+ self == c
161
+ end
162
+
163
+ # Returns a hash value for this Country.
164
+ def hash
165
+ code.hash
166
+ end
167
+
168
+ # Dumps this Country for marshalling.
169
+ def _dump(limit)
170
+ code
171
+ end
172
+
173
+ # Loads a marshalled Country.
174
+ def self._load(data)
175
+ Country.get(data)
176
+ 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
196
+ end