Class: TZInfo::DataSource Abstract
- Inherits:
-
Object
- Object
- TZInfo::DataSource
- Defined in:
- lib/tzinfo/data_source.rb
Overview
To create a custom data source, create a subclass of DataSource and implement the #load_timezone_info, #data_timezone_identifiers, #linked_timezone_identifiers, #load_country_info and #country_codes methods.
TZInfo can be used with different data sources for time zone and country data. Each source of data is implemented as a subclass of DataSource.
To choose a data source and override the default selection, use the DataSource.set method.
Direct Known Subclasses
TZInfo::DataSources::RubyDataSource, TZInfo::DataSources::ZoneinfoDataSource
Class Method Summary collapse
-
.get ⇒ DataSource
The currently selected source of data.
-
.set(data_source_or_type, *args) ⇒ Object
Sets the currently selected data source for time zone and country data.
Instance Method Summary collapse
-
#country_codes ⇒ Array<String>
Returns a frozen
Array
of all the available ISO 3166-1 alpha-2 country codes. -
#data_timezone_identifiers ⇒ Array<String>
Returns a frozen
Array
of all the available time zone identifiers for data time zones (i.e. those that actually contain definitions). -
#eager_load! ⇒ Object
Loads all timezone and country data into memory.
-
#get_country_info(code) ⇒ DataSources::CountryInfo
A TZInfo::DataSources::CountryInfo instance for the given ISO 3166-1 alpha-2 country code.
-
#get_timezone_info(identifier) ⇒ DataSources::TimezoneInfo
Returns a TZInfo::DataSources::TimezoneInfo instance for the given identifier.
-
#initialize ⇒ DataSource
constructor
Initializes a new DataSource instance.
-
#inspect ⇒ String
The internal object state as a programmer-readable
String
. -
#linked_timezone_identifiers ⇒ Array<String>
Returns a frozen
Array
of all the available time zone identifiers that are links to other time zones. -
#load_country_info(code) ⇒ DataSources::CountryInfo
protected
A TZInfo::DataSources::CountryInfo instance for the given ISO 3166-1 alpha-2 country code.
-
#load_timezone_info(identifier) ⇒ DataSources::TimezoneInfo
protected
Returns a TZInfo::DataSources::TimezoneInfo instance for the given time zone identifier.
-
#lookup_country_info(hash, code, encoding = Encoding::UTF_8) ⇒ DataSources::CountryInfo
protected
Looks up a given code in the given hash of code to TZInfo::DataSources::CountryInfo mappings.
-
#timezone_identifier_encoding ⇒ Encoding
protected
The
Encoding
used by theString
instances returned by #data_timezone_identifiers and #linked_timezone_identifiers. -
#timezone_identifiers ⇒ Array<String>
A frozen
Array
` of all the available time zone identifiers. -
#to_s ⇒ String
A description of the DataSource.
-
#validate_timezone_identifier(identifier) ⇒ String
protected
Checks that the given identifier is a valid time zone identifier (can be found in the #timezone_identifiers
Array
).
Constructor Details
#initialize ⇒ DataSource
Initializes a new TZInfo::DataSource instance. Typically only called via subclasses of TZInfo::DataSource.
166 167 168 |
# File 'lib/tzinfo/data_source.rb', line 166 def initialize @timezones = Concurrent::Map.new end |
Class Method Details
.get ⇒ DataSource
Returns the currently selected source of data.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/tzinfo/data_source.rb', line 42 def get # If a DataSource hasn't been manually set when the first request is # made to obtain a DataSource, then a default data source is created. # # This is done at the first request rather than when TZInfo is loaded to # avoid unnecessary attempts to find a suitable DataSource. # # A `Mutex` is used to ensure that only a single default instance is # created (this avoiding the possibility of retaining two copies of the # same data in memory). unless @@instance @@default_mutex.synchronize do set(create_default_data_source) unless @@instance end end @@instance end |
.set(data_source_or_type, *args) ⇒ Object
Sets the currently selected data source for time zone and country data.
This should usually be set to one of the two standard data source types:
:ruby
- read data from the Ruby modules included in the TZInfo::Data library (tzinfo-data gem).:zoneinfo
- read data from the zoneinfo files included with most Unix-like operating systems (e.g. in /usr/share/zoneinfo).
To set TZInfo to use one of the standard data source types, call
TZInfo::DataSource.set
` in one of the following ways:
TZInfo::DataSource.set(:ruby)
TZInfo::DataSource.set(:zoneinfo)
TZInfo::DataSource.set(:zoneinfo, zoneinfo_dir)
TZInfo::DataSource.set(:zoneinfo, zoneinfo_dir, iso3166_tab_file)
DataSource.set(:zoneinfo)
will automatically search for the zoneinfo
directory by checking the paths specified in
TZInfo::DataSources::ZoneinfoDataSource.search_path.
TZInfo::DataSources::ZoneinfoDirectoryNotFound will be raised if no valid
zoneinfo directory could be found.
DataSource.set(:zoneinfo, zoneinfo_dir)
uses the specified
zoneinfo_dir
directory as the data source. If the directory is not a
valid zoneinfo directory, a TZInfo::DataSources::InvalidZoneinfoDirectory
exception will be raised.
DataSource.set(:zoneinfo, zoneinfo_dir, iso3166_tab_file)
uses the
specified zoneinfo_dir
directory as the data source, but loads the
iso3166.tab
file from the path given by iso3166_tab_file
. If the
directory is not a valid zoneinfo directory, a
TZInfo::DataSources::InvalidZoneinfoDirectory exception will be raised.
Custom data sources can be created by subclassing TZInfo::DataSource and implementing the following methods:
- #load_timezone_info
- #data_timezone_identifiers
- #linked_timezone_identifiers
- #load_country_info
- #country_codes
To have TZInfo use the custom data source, call set, passing an instance of the custom data source implementation as follows:
TZInfo::DataSource.set(CustomDataSource.new)
Calling set will only affect instances of Timezone and Country obtained with Timezone.get and Country.get subsequent to the set call. Existing Timezone and Country instances will be unaffected.
If set is not called, TZInfo will by default attempt to use
TZInfo::Data as the data source. If TZInfo::Data is not available (i.e.
if require 'tzinfo/data'
fails), then TZInfo will search for a
zoneinfo directory instead (using the search path specified by
TZInfo::DataSources::ZoneinfoDataSource.search_path).
127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/tzinfo/data_source.rb', line 127 def set(data_source_or_type, *args) if data_source_or_type.kind_of?(DataSource) @@instance = data_source_or_type elsif data_source_or_type == :ruby @@instance = DataSources::RubyDataSource.new elsif data_source_or_type == :zoneinfo @@instance = DataSources::ZoneinfoDataSource.new(*args) else raise ArgumentError, 'data_source_or_type must be a DataSource instance or a data source type (:ruby or :zoneinfo)' end end |
Instance Method Details
#country_codes ⇒ Array<String>
Returns a frozen Array
of all the available ISO 3166-1 alpha-2 country
codes. The identifiers are sorted according to String#<=>
.
246 247 248 |
# File 'lib/tzinfo/data_source.rb', line 246 def country_codes raise_invalid_data_source('country_codes') end |
#data_timezone_identifiers ⇒ Array<String>
Returns a frozen Array
of all the available time zone identifiers for
data time zones (i.e. those that actually contain definitions). The
identifiers are sorted according to String#<=>
.
218 219 220 |
# File 'lib/tzinfo/data_source.rb', line 218 def data_timezone_identifiers raise_invalid_data_source('data_timezone_identifiers') end |
#eager_load! ⇒ Object
Loads all timezone and country data into memory.
This may be desirable in production environments to improve copy-on-write performance and to avoid flushing the constant cache every time a new timezone or country is loaded from TZInfo::DataSources::RubyDataSource.
255 256 257 258 259 |
# File 'lib/tzinfo/data_source.rb', line 255 def eager_load! timezone_identifiers.each {|identifier| load_timezone_info(identifier) } country_codes.each {|code| load_country_info(code) } nil end |
#get_country_info(code) ⇒ DataSources::CountryInfo
Returns a TZInfo::DataSources::CountryInfo instance for the given ISO 3166-1 alpha-2 country code.
237 238 239 |
# File 'lib/tzinfo/data_source.rb', line 237 def get_country_info(code) load_country_info(code) end |
#get_timezone_info(identifier) ⇒ DataSources::TimezoneInfo
Returns a TZInfo::DataSources::TimezoneInfo instance for the given identifier. The result will derive from either TZInfo::DataSources::DataTimezoneInfo for time zones that define their own data or TZInfo::DataSources::LinkedTimezoneInfo for links or aliases to other time zones.
#get_timezone_info calls #load_timezone_info to create the TZInfo::DataSources::TimezoneInfo instance. The returned instance is cached and returned in subsequent calls to #get_timezone_info for the identifier.
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/tzinfo/data_source.rb', line 184 def get_timezone_info(identifier) result = @timezones[identifier] unless result # Thread-safety: It is possible that multiple equivalent TimezoneInfo # instances could be created here in concurrently executing threads. The # consequences of this are that the data may be loaded more than once # (depending on the data source). The performance benefit of ensuring # that only a single instance is created is unlikely to be worth the # overhead of only allowing one TimezoneInfo to be loaded at a time. result = load_timezone_info(identifier) @timezones[result.identifier] = result end result end |
#inspect ⇒ String
Returns the internal object state as a programmer-readable
String
.
268 269 270 |
# File 'lib/tzinfo/data_source.rb', line 268 def inspect "#<#{self.class}>" end |
#linked_timezone_identifiers ⇒ Array<String>
Returns a frozen Array
of all the available time zone identifiers that
are links to other time zones. The identifiers are sorted according to
String#<=>
.
228 229 230 |
# File 'lib/tzinfo/data_source.rb', line 228 def linked_timezone_identifiers raise_invalid_data_source('linked_timezone_identifiers') end |
#load_country_info(code) ⇒ DataSources::CountryInfo (protected)
Returns a TZInfo::DataSources::CountryInfo instance for the given ISO 3166-1 alpha-2 country code.
294 295 296 |
# File 'lib/tzinfo/data_source.rb', line 294 def load_country_info(code) raise_invalid_data_source('load_country_info') end |
#load_timezone_info(identifier) ⇒ DataSources::TimezoneInfo (protected)
Returns a TZInfo::DataSources::TimezoneInfo instance for the given time zone identifier. The result should derive from either TZInfo::DataSources::DataTimezoneInfo for time zones that define their own data or TZInfo::DataSources::LinkedTimezoneInfo for links to or aliases for other time zones.
285 286 287 |
# File 'lib/tzinfo/data_source.rb', line 285 def load_timezone_info(identifier) raise_invalid_data_source('load_timezone_info') end |
#lookup_country_info(hash, code, encoding = Encoding::UTF_8) ⇒ DataSources::CountryInfo (protected)
Looks up a given code in the given hash of code to TZInfo::DataSources::CountryInfo mappings. If the code is found the TZInfo::DataSources::CountryInfo is returned. Otherwise an InvalidCountryCode exception is raised.
337 338 339 340 341 342 343 344 |
# File 'lib/tzinfo/data_source.rb', line 337 def lookup_country_info(hash, code, encoding = Encoding::UTF_8) raise InvalidCountryCode, "Invalid country code: #{code.nil? ? 'nil' : code}" unless code.kind_of?(String) info = try_with_encoding(code, encoding) {|c| hash[c] } return info if info raise InvalidCountryCode, "Invalid country code: #{code.encode(Encoding::UTF_8)}" end |
#timezone_identifier_encoding ⇒ Encoding (protected)
Returns the Encoding
used by the String
instances returned
by #data_timezone_identifiers and #linked_timezone_identifiers.
300 301 302 |
# File 'lib/tzinfo/data_source.rb', line 300 def timezone_identifier_encoding Encoding::UTF_8 end |
#timezone_identifiers ⇒ Array<String>
Returns a frozen Array
of all the available time zone
identifiers. The identifiers are sorted according to
String#<=>`.
204 205 206 207 208 209 210 |
# File 'lib/tzinfo/data_source.rb', line 204 def timezone_identifiers # Thread-safety: It is possible that the value of @timezone_identifiers # may be calculated multiple times in concurrently executing threads. It # is not worth the overhead of locking to ensure that # @timezone_identifiers is only calculated once. @timezone_identifiers ||= build_timezone_identifiers end |
#to_s ⇒ String
Returns a description of the TZInfo::DataSource.
262 263 264 |
# File 'lib/tzinfo/data_source.rb', line 262 def to_s "Default DataSource" end |
#validate_timezone_identifier(identifier) ⇒ String (protected)
Checks that the given identifier is a valid time zone identifier (can be
found in the #timezone_identifiers Array
). If the identifier is valid,
the String
instance representing that identifier from
timezone_identifiers
is returned. Otherwise an
InvalidTimezoneIdentifier exception is raised.
315 316 317 318 319 320 321 322 |
# File 'lib/tzinfo/data_source.rb', line 315 def validate_timezone_identifier(identifier) raise InvalidTimezoneIdentifier, "Invalid identifier: #{identifier.nil? ? 'nil' : identifier}" unless identifier.kind_of?(String) valid_identifier = try_with_encoding(identifier, timezone_identifier_encoding) {|id| find_timezone_identifier(id) } return valid_identifier if valid_identifier raise InvalidTimezoneIdentifier, "Invalid identifier: #{identifier.encode(Encoding::UTF_8)}" end |