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
@@ -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 1 version of TZInfo::Data.
5
+ #
6
+ # @private
7
+ module Format1 #:nodoc:
8
+ end
9
+ private_constant :Format1
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
@@ -0,0 +1,94 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ module TZInfo
5
+ module Format2
6
+ # Instances of {TimezoneDefiner} are yielded to TZInfo::Data modules by
7
+ # {TimezoneDefinition} to allow the offsets and transitions of the time zone
8
+ # to be specified.
9
+ #
10
+ # @private
11
+ class TimezoneDefiner #:nodoc:
12
+ # @return [Array<TimezoneTransition>] the defined transitions of the time
13
+ # zone.
14
+ attr_reader :transitions
15
+
16
+ # Initializes a new TimezoneDefiner.
17
+ #
18
+ # @param string_deduper [StringDeduper] a {StringDeduper} instance to use
19
+ # when deduping abbreviations.
20
+ def initialize(string_deduper)
21
+ @string_deduper = string_deduper
22
+ @offsets = {}
23
+ @transitions = []
24
+ end
25
+
26
+ # Returns the first offset to be defined or `nil` if no offsets have been
27
+ # defined. The first offset is observed before the time of the first
28
+ # transition.
29
+ #
30
+ # @return [TimezoneOffset] the first offset to be defined or `nil` if no
31
+ # offsets have been defined.
32
+ def first_offset
33
+ first = @offsets.first
34
+ first && first.last
35
+ end
36
+
37
+ # Defines an offset.
38
+ #
39
+ # @param id [Symbol] an arbitrary value used identify the offset in
40
+ # subsequent calls to transition. It must be unique.
41
+ # @param base_utc_offset [Integer] the base offset from UTC of the zone in
42
+ # seconds. This does not include daylight savings time.
43
+ # @param std_offset [Integer] the daylight savings offset from the base
44
+ # offset in seconds. Typically either 0 or 3600.
45
+ # @param abbreviation [String] an abbreviation for the offset, for
46
+ # example, EST or EDT.
47
+ # @raise [ArgumentError] if another offset has already been defined with
48
+ # the given id.
49
+ def offset(id, base_utc_offset, std_offset, abbreviation)
50
+ raise ArgumentError, 'An offset has already been defined with the given id' if @offsets.has_key?(id)
51
+
52
+ # Dedupe non-frozen literals from format 1 on all Ruby versions and
53
+ # format 2 on Ruby < 2.3 (without frozen_string_literal support).
54
+ abbreviation = @string_deduper.dedupe(abbreviation)
55
+
56
+ offset = TimezoneOffset.new(base_utc_offset, std_offset, abbreviation)
57
+ @offsets[id] = offset
58
+ @previous_offset ||= offset
59
+ end
60
+
61
+ # Defines a transition to a given offset.
62
+ #
63
+ # Transitions must be defined in increasing time order.
64
+ #
65
+ # @param offset_id [Symbol] references the id of a previously defined
66
+ # offset.
67
+ # @param timestamp_value [Integer] the time the transition occurs as a
68
+ # number of seconds since 1970-01-01 00:00:00 UTC ignoring leap seconds
69
+ # (i.e. each day is treated as if it were 86,400 seconds long).
70
+ # @raise [ArgumentError] if `offset_id` does not reference a defined
71
+ # offset.
72
+ # @raise [ArgumentError] if `timestamp_value` is not greater than the
73
+ # `timestamp_value` of the previously defined transition.
74
+ def transition(offset_id, timestamp_value)
75
+ offset = @offsets[offset_id]
76
+ raise ArgumentError, 'offset_id has not been defined' unless offset
77
+ raise ArgumentError, 'timestamp is not greater than the timestamp of the previously defined transition' if !@transitions.empty? && @transitions.last.timestamp_value >= timestamp_value
78
+ @transitions << TimezoneTransition.new(offset, @previous_offset, timestamp_value)
79
+ @previous_offset = offset
80
+ end
81
+
82
+ # Defines the rules that will be used for handling instants after the last
83
+ # transition.
84
+ #
85
+ # This method is currently just a placeholder for forward compatibility
86
+ # that accepts and ignores any arguments passed.
87
+ #
88
+ # Support for subsequent rules will be added in a future version of TZInfo
89
+ # and the rules will be included in format 2 releases of TZInfo::Data.
90
+ def subsequent_rules(*args)
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format2
5
+ # {Format2::TimezoneDefinition} is included into format 2 time zone
6
+ # definition modules and provides 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(ClassMethods)
16
+ end
17
+
18
+ # Class methods for inclusion.
19
+ #
20
+ # @private
21
+ module ClassMethods #:nodoc:
22
+ # @return [TimezoneInfo] the last time zone to be defined.
23
+ def get
24
+ @timezone
25
+ end
26
+
27
+ private
28
+
29
+ # @return [Class] the class to be instantiated and yielded by
30
+ # {#timezone}.
31
+ def timezone_definer_class
32
+ TimezoneDefiner
33
+ end
34
+
35
+ # Defines a data time zone.
36
+ #
37
+ # @param identifier [String] the identifier of the time zone.
38
+ # @yield [definer] yields to the caller to define the time zone.
39
+ # @yieldparam definer [Object] an instance of the class returned by
40
+ # {#timezone_definer_class}, typically {TimezoneDefiner}.
41
+ def timezone(identifier)
42
+ # Dedupe non-frozen literals from format 1 on all Ruby versions and
43
+ # format 2 on Ruby < 2.3 (without frozen_string_literal support).
44
+ string_deduper = StringDeduper.global
45
+ identifier = string_deduper.dedupe(identifier)
46
+
47
+ definer = timezone_definer_class.new(string_deduper)
48
+ yield definer
49
+ transitions = definer.transitions
50
+
51
+ @timezone = if transitions.empty?
52
+ DataSources::ConstantOffsetDataTimezoneInfo.new(identifier, definer.first_offset)
53
+ else
54
+ DataSources::TransitionsDataTimezoneInfo.new(identifier, transitions)
55
+ end
56
+ end
57
+
58
+ # Defines a linked time zone.
59
+ #
60
+ # @param identifier [String] the identifier of the time zone being
61
+ # defined.
62
+ # @param link_to_identifier [String] the identifier the new time zone
63
+ # links to (is an alias for).
64
+ def linked_timezone(identifier, link_to_identifier)
65
+ # Dedupe non-frozen literals from format 1 on all Ruby versions and
66
+ # format 2 on Ruby < 2.3 (without frozen_string_literal support).
67
+ string_deduper = StringDeduper.global
68
+ @timezone = DataSources::LinkedTimezoneInfo.new(string_deduper.dedupe(identifier), string_deduper.dedupe(link_to_identifier))
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format2
5
+ # Instances of {TimezoneIndexDefiner} are yielded by
6
+ # {TimezoneIndexDefinition} to allow the time zone index to be defined.
7
+ #
8
+ # @private
9
+ class TimezoneIndexDefiner #:nodoc:
10
+ # @return [Array<String>] the identifiers of all data time zones.
11
+ attr_reader :data_timezones
12
+
13
+ # @return [Array<String>] the identifiers of all linked time zones.
14
+ attr_reader :linked_timezones
15
+
16
+ # Initializes a new TimezoneDefiner.
17
+ #
18
+ # @param string_deduper [StringDeduper] a {StringDeduper} instance to use
19
+ # when deduping identifiers.
20
+ def initialize(string_deduper)
21
+ @string_deduper = string_deduper
22
+ @data_timezones = []
23
+ @linked_timezones = []
24
+ end
25
+
26
+ # Adds a data time zone to the index.
27
+ #
28
+ # @param identifier [String] the time zone identifier.
29
+ def data_timezone(identifier)
30
+ # Dedupe non-frozen literals from format 1 on all Ruby versions and
31
+ # format 2 on Ruby < 2.3 (without frozen_string_literal support).
32
+ @data_timezones << @string_deduper.dedupe(identifier)
33
+ end
34
+
35
+ # Adds a linked time zone to the index.
36
+ #
37
+ # @param identifier [String] the time zone identifier.
38
+ def linked_timezone(identifier)
39
+ # Dedupe non-frozen literals from format 1 on all Ruby versions and
40
+ # format 2 on Ruby < 2.3 (without frozen_string_literal support).
41
+ @linked_timezones << @string_deduper.dedupe(identifier)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: UTF-8
2
+
3
+ module TZInfo
4
+ module Format2
5
+ # The format 2 time zone index file includes {TimezoneIndexDefinition},
6
+ # which provides the {TimezoneIndexDefinition::ClassMethods#timezone_index
7
+ # timezone_index} method used to define 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
+ empty = [].freeze
20
+ @timezones = empty
21
+ @data_timezones = empty
22
+ @linked_timezones = empty
23
+ end
24
+ end
25
+
26
+ # Class methods for inclusion.
27
+ #
28
+ # @private
29
+ module ClassMethods #:nodoc:
30
+ # @return [Array<String>] a frozen `Array` containing the identifiers of
31
+ # all data time zones. Identifiers are sorted according to
32
+ # `String#<=>`.
33
+ attr_reader :data_timezones
34
+
35
+ # @return [Array<String>] a frozen `Array` containing the identifiers of
36
+ # all linked time zones. Identifiers are sorted according to
37
+ # `String#<=>`.
38
+ attr_reader :linked_timezones
39
+
40
+ # Defines the index.
41
+ #
42
+ # @yield [definer] yields to the caller to allow the index to be
43
+ # defined.
44
+ # @yieldparam definer [TimezoneIndexDefiner] a {TimezoneIndexDefiner}
45
+ # instance that should be used to define the index.
46
+ def timezone_index
47
+ definer = TimezoneIndexDefiner.new(StringDeduper.global)
48
+ yield definer
49
+ @data_timezones = definer.data_timezones.sort!.freeze
50
+ @linked_timezones = definer.linked_timezones.sort!.freeze
51
+ end
52
+ end
53
+ end
54
+ end
55
+ 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
@@ -1,30 +1,35 @@
1
+ # encoding: UTF-8
2
+
1
3
  module TZInfo
2
4
 
3
- # A Timezone based on a TimezoneInfo.
5
+ # A {Timezone} based on a {DataSources::TimezoneInfo}.
4
6
  #
5
- # @private
6
- class InfoTimezone < Timezone #:nodoc:
7
-
8
- # Constructs a new InfoTimezone with a TimezoneInfo instance.
9
- def self.new(info)
10
- tz = super()
11
- tz.send(:setup, info)
12
- tz
7
+ # @abstract
8
+ class InfoTimezone < Timezone
9
+ # Initializes a new {InfoTimezone}.
10
+ #
11
+ # {InfoTimezone} instances should not normally be created directly. Use
12
+ # the {Timezone.get} method to obtain {Timezone} instances.
13
+ #
14
+ # @param info [DataSources::TimezoneInfo] a {DataSources::TimezoneInfo}
15
+ # instance supplied by a {DataSource} that will be used as the source of
16
+ # data for this {InfoTimezone}.
17
+ def initialize(info)
18
+ super()
19
+ @info = info
13
20
  end
14
-
15
- # The identifier of the timezone, e.g. "Europe/Paris".
21
+
22
+ # (see Timezone#identifier)
16
23
  def identifier
17
24
  @info.identifier
18
25
  end
19
-
26
+
20
27
  protected
21
- # The TimezoneInfo for this Timezone.
22
- def info
23
- @info
24
- end
25
-
26
- def setup(info)
27
- @info = info
28
- end
29
- end
28
+
29
+ # @return [DataSources::TimezoneInfo] the {DataSources::TimezoneInfo} this
30
+ # {InfoTimezone} is based on.
31
+ def info
32
+ @info
33
+ end
34
+ end
30
35
  end