tzinfo 1.2.7 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.yardopts +3 -0
  5. data/CHANGES.md +489 -382
  6. data/LICENSE +12 -12
  7. data/README.md +368 -114
  8. data/lib/tzinfo.rb +59 -29
  9. data/lib/tzinfo/country.rb +141 -129
  10. data/lib/tzinfo/country_timezone.rb +70 -112
  11. data/lib/tzinfo/data_source.rb +389 -144
  12. data/lib/tzinfo/data_sources.rb +8 -0
  13. data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
  14. data/lib/tzinfo/data_sources/country_info.rb +42 -0
  15. data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
  16. data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
  17. data/lib/tzinfo/data_sources/ruby_data_source.rb +145 -0
  18. data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
  19. data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
  20. data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +577 -0
  21. data/lib/tzinfo/data_sources/zoneinfo_reader.rb +288 -0
  22. data/lib/tzinfo/data_timezone.rb +33 -47
  23. data/lib/tzinfo/datetime_with_offset.rb +153 -0
  24. data/lib/tzinfo/format1.rb +10 -0
  25. data/lib/tzinfo/format1/country_definer.rb +17 -0
  26. data/lib/tzinfo/format1/country_index_definition.rb +64 -0
  27. data/lib/tzinfo/format1/timezone_definer.rb +64 -0
  28. data/lib/tzinfo/format1/timezone_definition.rb +39 -0
  29. data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
  30. data/lib/tzinfo/format2.rb +10 -0
  31. data/lib/tzinfo/format2/country_definer.rb +68 -0
  32. data/lib/tzinfo/format2/country_index_definer.rb +68 -0
  33. data/lib/tzinfo/format2/country_index_definition.rb +46 -0
  34. data/lib/tzinfo/format2/timezone_definer.rb +94 -0
  35. data/lib/tzinfo/format2/timezone_definition.rb +73 -0
  36. data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
  37. data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
  38. data/lib/tzinfo/info_timezone.rb +26 -21
  39. data/lib/tzinfo/linked_timezone.rb +33 -52
  40. data/lib/tzinfo/offset_timezone_period.rb +42 -0
  41. data/lib/tzinfo/string_deduper.rb +118 -0
  42. data/lib/tzinfo/time_with_offset.rb +128 -0
  43. data/lib/tzinfo/timestamp.rb +548 -0
  44. data/lib/tzinfo/timestamp_with_offset.rb +85 -0
  45. data/lib/tzinfo/timezone.rb +989 -502
  46. data/lib/tzinfo/timezone_offset.rb +84 -74
  47. data/lib/tzinfo/timezone_period.rb +151 -217
  48. data/lib/tzinfo/timezone_proxy.rb +70 -79
  49. data/lib/tzinfo/timezone_transition.rb +77 -109
  50. data/lib/tzinfo/transitions_timezone_period.rb +63 -0
  51. data/lib/tzinfo/untaint_ext.rb +18 -0
  52. data/lib/tzinfo/version.rb +7 -0
  53. data/lib/tzinfo/with_offset.rb +61 -0
  54. metadata +42 -98
  55. metadata.gz.sig +0 -0
  56. data/Rakefile +0 -107
  57. data/lib/tzinfo/country_index_definition.rb +0 -31
  58. data/lib/tzinfo/country_info.rb +0 -42
  59. data/lib/tzinfo/data_timezone_info.rb +0 -55
  60. data/lib/tzinfo/linked_timezone_info.rb +0 -26
  61. data/lib/tzinfo/offset_rationals.rb +0 -77
  62. data/lib/tzinfo/ruby_core_support.rb +0 -169
  63. data/lib/tzinfo/ruby_country_info.rb +0 -74
  64. data/lib/tzinfo/ruby_data_source.rb +0 -140
  65. data/lib/tzinfo/time_or_datetime.rb +0 -340
  66. data/lib/tzinfo/timezone_definition.rb +0 -36
  67. data/lib/tzinfo/timezone_index_definition.rb +0 -54
  68. data/lib/tzinfo/timezone_info.rb +0 -30
  69. data/lib/tzinfo/timezone_transition_definition.rb +0 -104
  70. data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
  71. data/lib/tzinfo/zoneinfo_country_info.rb +0 -37
  72. data/lib/tzinfo/zoneinfo_data_source.rb +0 -496
  73. data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -300
  74. data/test/tc_country.rb +0 -238
  75. data/test/tc_country_index_definition.rb +0 -69
  76. data/test/tc_country_info.rb +0 -16
  77. data/test/tc_country_timezone.rb +0 -173
  78. data/test/tc_data_source.rb +0 -218
  79. data/test/tc_data_timezone.rb +0 -99
  80. data/test/tc_data_timezone_info.rb +0 -18
  81. data/test/tc_info_timezone.rb +0 -34
  82. data/test/tc_linked_timezone.rb +0 -155
  83. data/test/tc_linked_timezone_info.rb +0 -23
  84. data/test/tc_offset_rationals.rb +0 -23
  85. data/test/tc_ruby_core_support.rb +0 -168
  86. data/test/tc_ruby_country_info.rb +0 -110
  87. data/test/tc_ruby_data_source.rb +0 -167
  88. data/test/tc_time_or_datetime.rb +0 -660
  89. data/test/tc_timezone.rb +0 -1361
  90. data/test/tc_timezone_definition.rb +0 -113
  91. data/test/tc_timezone_index_definition.rb +0 -73
  92. data/test/tc_timezone_info.rb +0 -11
  93. data/test/tc_timezone_london.rb +0 -143
  94. data/test/tc_timezone_melbourne.rb +0 -142
  95. data/test/tc_timezone_new_york.rb +0 -142
  96. data/test/tc_timezone_offset.rb +0 -126
  97. data/test/tc_timezone_period.rb +0 -555
  98. data/test/tc_timezone_proxy.rb +0 -136
  99. data/test/tc_timezone_transition.rb +0 -366
  100. data/test/tc_timezone_transition_definition.rb +0 -295
  101. data/test/tc_timezone_utc.rb +0 -27
  102. data/test/tc_transition_data_timezone_info.rb +0 -433
  103. data/test/tc_zoneinfo_country_info.rb +0 -78
  104. data/test/tc_zoneinfo_data_source.rb +0 -1204
  105. data/test/tc_zoneinfo_timezone_info.rb +0 -1236
  106. data/test/test_utils.rb +0 -192
  107. data/test/ts_all.rb +0 -7
  108. data/test/ts_all_ruby.rb +0 -5
  109. data/test/ts_all_zoneinfo.rb +0 -9
  110. data/test/tzinfo-data/tzinfo/data.rb +0 -8
  111. data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
  112. data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -315
  113. data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -218
  114. data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
  115. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
  116. data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
  117. data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
  118. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -261
  119. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -186
  120. data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -321
  121. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -265
  122. data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -220
  123. data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
  124. data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -927
  125. data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -596
  126. data/test/tzinfo-data/tzinfo/data/version.rb +0 -14
  127. data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
  128. data/test/zoneinfo/America/New_York +0 -0
  129. data/test/zoneinfo/Australia/Melbourne +0 -0
  130. data/test/zoneinfo/EST +0 -0
  131. data/test/zoneinfo/Etc/UTC +0 -0
  132. data/test/zoneinfo/Europe/Amsterdam +0 -0
  133. data/test/zoneinfo/Europe/Andorra +0 -0
  134. data/test/zoneinfo/Europe/London +0 -0
  135. data/test/zoneinfo/Europe/Paris +0 -0
  136. data/test/zoneinfo/Europe/Prague +0 -0
  137. data/test/zoneinfo/Factory +0 -0
  138. data/test/zoneinfo/iso3166.tab +0 -275
  139. data/test/zoneinfo/leapseconds +0 -61
  140. data/test/zoneinfo/posix/Europe/London +0 -0
  141. data/test/zoneinfo/posixrules +0 -0
  142. data/test/zoneinfo/right/Europe/London +0 -0
  143. data/test/zoneinfo/zone.tab +0 -439
  144. data/test/zoneinfo/zone1970.tab +0 -369
  145. data/tzinfo.gemspec +0 -21
@@ -0,0 +1,10 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ # Modules and classes used by the format 1 version of TZInfo::Data.
5
+ #
6
+ # @private
7
+ module Format1 #:nodoc:
8
+ end
9
+ private_constant :Format1
10
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format1
5
+ # Instances of {Format1::CountryDefiner} are yielded to the format 1 version
6
+ # of `TZInfo::Data::Indexes::Countries` by {CountryIndexDefinition} to allow
7
+ # the zones of a country to be specified.
8
+ #
9
+ # @private
10
+ class CountryDefiner < Format2::CountryDefiner #:nodoc:
11
+ # Initializes a new {CountryDefiner}.
12
+ def initialize(identifier_deduper, description_deduper)
13
+ super(nil, identifier_deduper, description_deduper)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format1
5
+ # The format 1 TZInfo::Data country index file includes
6
+ # {Format1::CountryIndexDefinition}, which provides a
7
+ # {CountryIndexDefinition::ClassMethods#country country} method used to
8
+ # define each country in the index.
9
+ #
10
+ # @private
11
+ module CountryIndexDefinition #:nodoc:
12
+ # Adds class methods to the includee and initializes class instance
13
+ # variables.
14
+ #
15
+ # @param base [Module] the includee.
16
+ def self.append_features(base)
17
+ super
18
+ base.extend(ClassMethods)
19
+ base.instance_eval { @countries = {} }
20
+ end
21
+
22
+ # Class methods for inclusion.
23
+ #
24
+ # @private
25
+ module ClassMethods #:nodoc:
26
+ # @return [Hash<String, DataSources::CountryInfo>] a frozen `Hash`
27
+ # of all the countries that have been defined in the index keyed by
28
+ # their codes.
29
+ def countries
30
+ @description_deduper = nil
31
+ @countries.freeze
32
+ end
33
+
34
+ private
35
+
36
+ # Defines a country with an ISO 3166-1 alpha-2 country code and name.
37
+ #
38
+ # @param code [String] the ISO 3166-1 alpha-2 country code.
39
+ # @param name [String] the name of the country.
40
+ # @yield [definer] (optional) to obtain the time zones for the country.
41
+ # @yieldparam definer [CountryDefiner] a {CountryDefiner} instance.
42
+ def country(code, name)
43
+ @description_deduper ||= StringDeduper.new
44
+
45
+ zones = if block_given?
46
+ definer = CountryDefiner.new(StringDeduper.global, @description_deduper)
47
+ yield definer
48
+ definer.timezones
49
+ else
50
+ []
51
+ end
52
+
53
+ @countries[code.freeze] = DataSources::CountryInfo.new(code, name, zones)
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ # Alias used by TZInfo::Data format1 releases.
60
+ #
61
+ # @private
62
+ CountryIndexDefinition = Format1::CountryIndexDefinition #:nodoc:
63
+ private_constant :CountryIndexDefinition
64
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ module Format1
6
+ # Instances of {Format1::TimezoneDefiner} are yielded to TZInfo::Data
7
+ # format 1 modules by {TimezoneDefinition} to allow the offsets and
8
+ # transitions of the time zone to be specified.
9
+ #
10
+ # @private
11
+ class TimezoneDefiner < Format2::TimezoneDefiner #:nodoc:
12
+ undef_method :subsequent_rules
13
+
14
+ # Defines an offset.
15
+ #
16
+ # @param id [Symbol] an arbitrary value used identify the offset in
17
+ # subsequent calls to transition. It must be unique.
18
+ # @param utc_offset [Integer] the base offset from UTC of the zone in
19
+ # seconds. This does not include daylight savings time.
20
+ # @param std_offset [Integer] the daylight savings offset from the base
21
+ # offset in seconds. Typically either 0 or 3600.
22
+ # @param abbreviation [Symbol] an abbreviation for the offset, for
23
+ # example, `:EST` or `:EDT`.
24
+ # @raise [ArgumentError] if another offset has already been defined with
25
+ # the given id.
26
+ def offset(id, utc_offset, std_offset, abbreviation)
27
+ super(id, utc_offset, std_offset, abbreviation.to_s)
28
+ end
29
+
30
+ # Defines a transition to a given offset.
31
+ #
32
+ # Transitions must be defined in increasing time order.
33
+ #
34
+ # @param year [Integer] the UTC year in which the transition occurs. Used
35
+ # in earlier versions of TZInfo, but now ignored.
36
+ # @param month [Integer] the UTC month in which the transition occurs.
37
+ # Used in earlier versions of TZInfo, but now ignored.
38
+ # @param offset_id [Symbol] references the id of a previously defined
39
+ # offset (see #offset).
40
+ # @param timestamp_value [Integer] the time the transition occurs as an
41
+ # Integer number of seconds since 1970-01-01 00:00:00 UTC ignoring leap
42
+ # seconds (i.e. each day is treated as if it were 86,400 seconds long).
43
+ # @param datetime_numerator [Integer] the time of the transition as the
44
+ # numerator of the `Rational` returned by `DateTime#ajd`. Used in
45
+ # earlier versions of TZInfo, but now ignored.
46
+ # @param datetime_denominator [Integer] the time of the transition as the
47
+ # denominator of the `Rational` returned by `DateTime#ajd`. Used in
48
+ # earlier versions of TZInfo, but now ignored.
49
+ # @raise [ArgumentError] if `offset_id` does not reference a defined
50
+ # offset.
51
+ # @raise [ArgumentError] if `timestamp_value` is not greater than the
52
+ # `timestamp_value` of the previously defined transition.
53
+ # @raise [ArgumentError] if `datetime_numerator` is specified, but
54
+ # `datetime_denominator` is not. In older versions of TZInfo, it was
55
+ # possible to define a transition with the `DateTime` numerator as the
56
+ # 4th parameter and the denominator as the 5th parameter. This style of
57
+ # definition is not used in released versions of TZInfo::Data.
58
+ def transition(year, month, offset_id, timestamp_value, datetime_numerator = nil, datetime_denominator = nil)
59
+ raise ArgumentError, 'DateTime-only transitions are not supported' if datetime_numerator && !datetime_denominator
60
+ super(offset_id, timestamp_value)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format1
5
+ # {Format1::TimezoneDefinition} is included into format 1 time zone
6
+ # definition modules and provides the methods for defining time zones.
7
+ #
8
+ # @private
9
+ module TimezoneDefinition #:nodoc:
10
+ # Adds class methods to the includee.
11
+ #
12
+ # @param base [Module] the includee.
13
+ def self.append_features(base)
14
+ super
15
+ base.extend(Format2::TimezoneDefinition::ClassMethods)
16
+ base.extend(ClassMethods)
17
+ end
18
+
19
+ # Class methods for inclusion.
20
+ #
21
+ # @private
22
+ module ClassMethods #:nodoc:
23
+ private
24
+
25
+ # @return the class to be instantiated and yielded by
26
+ # {Format2::TimezoneDefinition::ClassMethods#timezone}.
27
+ def timezone_definer_class
28
+ TimezoneDefiner
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ # Alias used by TZInfo::Data format1 releases.
35
+ #
36
+ # @private
37
+ TimezoneDefinition = Format1::TimezoneDefinition #:nodoc:
38
+ private_constant :TimezoneDefinition
39
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format1
5
+ # The format 1 TZInfo::Data time zone index file includes
6
+ # {Format1::TimezoneIndexDefinition}, which provides methods used to define
7
+ # time zones in the index.
8
+ #
9
+ # @private
10
+ module TimezoneIndexDefinition #:nodoc:
11
+ # Adds class methods to the includee and initializes class instance
12
+ # variables.
13
+ #
14
+ # @param base [Module] the includee.
15
+ def self.append_features(base)
16
+ super
17
+ base.extend(ClassMethods)
18
+ base.instance_eval do
19
+ @timezones = []
20
+ @data_timezones = []
21
+ @linked_timezones = []
22
+ end
23
+ end
24
+
25
+ # Class methods for inclusion.
26
+ #
27
+ # @private
28
+ module ClassMethods #:nodoc:
29
+ # @return [Array<String>] a frozen `Array` containing the identifiers of
30
+ # all data time zones. Identifiers are sorted according to
31
+ # `String#<=>`.
32
+ def data_timezones
33
+ unless @data_timezones.frozen?
34
+ @data_timezones = @data_timezones.sort.freeze
35
+ end
36
+ @data_timezones
37
+ end
38
+
39
+ # @return [Array<String>] a frozen `Array` containing the identifiers of
40
+ # all linked time zones. Identifiers are sorted according to
41
+ # `String#<=>`.
42
+ def linked_timezones
43
+ unless @linked_timezones.frozen?
44
+ @linked_timezones = @linked_timezones.sort.freeze
45
+ end
46
+ @linked_timezones
47
+ end
48
+
49
+ private
50
+
51
+ # Adds a data time zone to the index.
52
+ #
53
+ # @param identifier [String] the time zone identifier.
54
+ def timezone(identifier)
55
+ identifier = StringDeduper.global.dedupe(identifier)
56
+ @timezones << identifier
57
+ @data_timezones << identifier
58
+ end
59
+
60
+ # Adds a linked time zone to the index.
61
+ #
62
+ # @param identifier [String] the time zone identifier.
63
+ def linked_timezone(identifier)
64
+ identifier = StringDeduper.global.dedupe(identifier)
65
+ @timezones << identifier
66
+ @linked_timezones << identifier
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ # Alias used by TZInfo::Data format 1 releases.
73
+ #
74
+ # @private
75
+ TimezoneIndexDefinition = Format1::TimezoneIndexDefinition #:nodoc:
76
+ private_constant :TimezoneIndexDefinition
77
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ # Modules and classes used by the format 2 version of TZInfo::Data.
5
+ #
6
+ # @private
7
+ module Format2 #:nodoc:
8
+ end
9
+ private_constant :Format2
10
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ module Format2
6
+ # Instances of {Format2::CountryDefiner} are yielded to the format 2 version
7
+ # of `TZInfo::Data::Indexes::Countries` by {CountryIndexDefiner} to allow
8
+ # the zones of a country to be specified.
9
+ #
10
+ # @private
11
+ class CountryDefiner #:nodoc:
12
+ # @return [Array<CountryTimezone>] the time zones observed in the country.
13
+ attr_reader :timezones
14
+
15
+ # Initializes a new {CountryDefiner}.
16
+ #
17
+ # @param shared_timezones [Hash<Symbol, CountryTimezone>] a `Hash`
18
+ # containing time zones shared by more than one country, keyed by a
19
+ # unique reference.
20
+ # @param identifier_deduper [StringDeduper] a {StringDeduper} instance to
21
+ # use when deduping time zone identifiers.
22
+ # @param description_deduper [StringDeduper] a {StringDeduper} instance to
23
+ # use when deduping time zone descriptions.
24
+ def initialize(shared_timezones, identifier_deduper, description_deduper)
25
+ @shared_timezones = shared_timezones
26
+ @identifier_deduper = identifier_deduper
27
+ @description_deduper = description_deduper
28
+ @timezones = []
29
+ end
30
+
31
+ # @overload timezone(reference)
32
+ # Defines a time zone of a country as a reference to a pre-defined
33
+ # shared time zone.
34
+ # @param reference [Symbol] a reference for a pre-defined shared time
35
+ # zone.
36
+ # @overload timezone(identifier, latitude_numerator, latitude_denominator, longitude_numerator, longitude_denominator, description)
37
+ # Defines a (non-shared) time zone of a country. The latitude and
38
+ # longitude are given as the numerator and denominator of a `Rational`.
39
+ # @param identifier [String] the time zone identifier.
40
+ # @param latitude_numerator [Integer] the numerator of the latitude.
41
+ # @param latitude_denominator [Integer] the denominator of the latitude.
42
+ # @param longitude_numerator [Integer] the numerator of the longitude.
43
+ # @param longitude_denominator [Integer] the denominator of the
44
+ # longitude.
45
+ # @param description [String] an optional description for the time zone.
46
+ def timezone(identifier_or_reference, latitude_numerator = nil,
47
+ latitude_denominator = nil, longitude_numerator = nil,
48
+ longitude_denominator = nil, description = nil)
49
+ if latitude_numerator
50
+ unless latitude_denominator && longitude_numerator && longitude_denominator
51
+ raise ArgumentError, 'Either just a reference should be supplied, or the identifier, latitude and longitude must all be specified'
52
+ end
53
+
54
+ # Dedupe non-frozen literals from format 1 on all Ruby versions and
55
+ # format 2 on Ruby < 2.3 (without frozen_string_literal support).
56
+
57
+ @timezones << CountryTimezone.new(@identifier_deduper.dedupe(identifier_or_reference),
58
+ Rational(latitude_numerator, latitude_denominator),
59
+ Rational(longitude_numerator, longitude_denominator), description && @description_deduper.dedupe(description))
60
+ else
61
+ shared_timezone = @shared_timezones[identifier_or_reference]
62
+ raise ArgumentError, "Unknown shared timezone: #{identifier_or_reference}" unless shared_timezone
63
+ @timezones << shared_timezone
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format2
5
+ # Instances of {Format2::CountryIndexDefiner} are yielded to the format 2
6
+ # version of `TZInfo::Data::Indexes::Countries` by {CountryIndexDefinition}
7
+ # to allow countries and their time zones to be specified.
8
+ #
9
+ # @private
10
+ class CountryIndexDefiner #:nodoc:
11
+ # @return [Hash<String, CountryInfo>] a `Hash` of all the countries that
12
+ # have been defined in the index keyed by their codes.
13
+ attr_reader :countries
14
+
15
+ # Initializes a new {CountryIndexDefiner}.
16
+ #
17
+ # @param identifier_deduper [StringDeduper] a {StringDeduper} instance to
18
+ # use when deduping time zone identifiers.
19
+ # @param description_deduper [StringDeduper] a {StringDeduper} instance to
20
+ # use when deduping time zone descriptions.
21
+ def initialize(identifier_deduper, description_deduper)
22
+ @identifier_deduper = identifier_deduper
23
+ @description_deduper = description_deduper
24
+ @shared_timezones = {}
25
+ @countries = {}
26
+ end
27
+
28
+ # Defines a time zone shared by many countries with an reference for
29
+ # subsequent use in country definitions. The latitude and longitude are
30
+ # given as the numerator and denominator of a `Rational`.
31
+ #
32
+ # @param reference [Symbol] a unique reference for the time zone.
33
+ # @param identifier [String] the time zone identifier.
34
+ # @param latitude_numerator [Integer] the numerator of the latitude.
35
+ # @param latitude_denominator [Integer] the denominator of the latitude.
36
+ # @param longitude_numerator [Integer] the numerator of the longitude.
37
+ # @param longitude_denominator [Integer] the denominator of the longitude.
38
+ # @param description [String] an optional description for the time zone.
39
+ def timezone(reference, identifier, latitude_numerator, latitude_denominator,
40
+ longitude_numerator, longitude_denominator, description = nil)
41
+ # Dedupe non-frozen literals from format 1 on all Ruby versions and
42
+ # format 2 on Ruby < 2.3 (without frozen_string_literal support).
43
+ @shared_timezones[reference] = CountryTimezone.new(@identifier_deduper.dedupe(identifier),
44
+ Rational(latitude_numerator, latitude_denominator),
45
+ Rational(longitude_numerator, longitude_denominator), description && @description_deduper.dedupe(description))
46
+ end
47
+
48
+ # Defines a country.
49
+ #
50
+ # @param code [String] The ISO 3166-1 alpha-2 code of the country.
51
+ # @param name [String] Then name of the country.
52
+ # @yield [definer] yields (optional) to obtain the time zones for the
53
+ # country.
54
+ # @yieldparam definer [CountryDefiner] a {CountryDefiner}
55
+ # instance that should be used to specify the time zones of the country.
56
+ def country(code, name)
57
+ timezones = if block_given?
58
+ definer = CountryDefiner.new(@shared_timezones, @identifier_deduper, @description_deduper)
59
+ yield definer
60
+ definer.timezones
61
+ else
62
+ []
63
+ end
64
+ @countries[code.freeze] = DataSources::CountryInfo.new(code, name, timezones)
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format2
5
+ # The format 2 country index file includes
6
+ # {Format2::CountryIndexDefinition}, which provides a
7
+ # {CountryIndexDefinition::ClassMethods#country_index country_index} method
8
+ # used to define the country index.
9
+ #
10
+ # @private
11
+ module CountryIndexDefinition #:nodoc:
12
+ # Adds class methods to the includee and initializes class instance
13
+ # variables.
14
+ #
15
+ # @param base [Module] the includee.
16
+ def self.append_features(base)
17
+ super
18
+ base.extend(ClassMethods)
19
+ base.instance_eval { @countries = {}.freeze }
20
+ end
21
+
22
+ # Class methods for inclusion.
23
+ #
24
+ # @private
25
+ module ClassMethods #:nodoc:
26
+ # @return [Hash<String, DataSources::CountryInfo>] a frozen `Hash`
27
+ # of all the countries that have been defined in the index keyed by
28
+ # their codes.
29
+ attr_reader :countries
30
+
31
+ private
32
+
33
+ # Defines the index.
34
+ #
35
+ # @yield [definer] yields to allow the index to be defined.
36
+ # @yieldparam definer [CountryIndexDefiner] a {CountryIndexDefiner}
37
+ # instance that should be used to define the index.
38
+ def country_index
39
+ definer = CountryIndexDefiner.new(StringDeduper.global, StringDeduper.new)
40
+ yield definer
41
+ @countries = definer.countries.freeze
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end