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
@@ -1,136 +0,0 @@
1
- # encoding: UTF-8
2
- # frozen_string_literal: true
3
-
4
- require 'strscan'
5
-
6
- module TZInfo
7
- # An {InvalidPosixTimeZone} exception is raised if an invalid POSIX-style
8
- # time zone string is encountered.
9
- #
10
- # @private
11
- class InvalidPosixTimeZone < StandardError #:nodoc:
12
- end
13
-
14
- # A parser for POSIX-style TZ strings used in zoneinfo files and specified
15
- # by tzfile.5 and tzset.3.
16
- #
17
- # @private
18
- class PosixTimeZoneParser #:nodoc:
19
- # Parses a POSIX-style TZ string, returning either a TimezoneOffset or
20
- # an AnnualRules instance.
21
- def parse(tz_string)
22
- raise InvalidPosixTimeZone unless tz_string.kind_of?(String)
23
- return nil if tz_string.empty?
24
-
25
- s = StringScanner.new(tz_string)
26
- check_scan(s, /([^-+,\d<][^-+,\d]*) | <([^>]+)>/x)
27
- std_abbrev = s[1] || s[2]
28
- check_scan(s, /([-+]?\d+)(?::(\d+)(?::(\d+))?)?/)
29
- std_offset = get_offset_from_hms(s[1], s[2], s[3])
30
-
31
- if s.scan(/([^-+,\d<][^-+,\d]*) | <([^>]+)>/x)
32
- dst_abbrev = s[1] || s[2]
33
-
34
- if s.scan(/([-+]?\d+)(?::(\d+)(?::(\d+))?)?/)
35
- dst_offset = get_offset_from_hms(s[1], s[2], s[3])
36
- else
37
- # POSIX is negative for ahead of UTC.
38
- dst_offset = std_offset - 3600
39
- end
40
-
41
- dst_difference = std_offset - dst_offset
42
-
43
- start_rule = parse_rule(s, 'start')
44
- end_rule = parse_rule(s, 'end')
45
-
46
- raise InvalidPosixTimeZone, "Expected the end of a POSIX-style time zone string but found '#{s.rest}'." if s.rest?
47
-
48
- if start_rule.is_always_first_day_of_year? && start_rule.transition_at == 0 &&
49
- end_rule.is_always_last_day_of_year? && end_rule.transition_at == 86400 + dst_difference
50
- # Constant daylight savings time.
51
- # POSIX is negative for ahead of UTC.
52
- TimezoneOffset.new(-std_offset, dst_difference, dst_abbrev.to_sym)
53
- else
54
- AnnualRules.new(
55
- TimezoneOffset.new(-std_offset, 0, std_abbrev.to_sym),
56
- TimezoneOffset.new(-std_offset, dst_difference, dst_abbrev.to_sym),
57
- start_rule,
58
- end_rule)
59
- end
60
- elsif !s.rest?
61
- # Constant standard time.
62
- # POSIX is negative for ahead of UTC.
63
- TimezoneOffset.new(-std_offset, 0, std_abbrev.to_sym)
64
- else
65
- raise InvalidPosixTimeZone, "Expected the end of a POSIX-style time zone string but found '#{s.rest}'."
66
- end
67
- end
68
-
69
- private
70
-
71
- # Parses the rule from the TZ string, returning a TransitionRule.
72
- def parse_rule(s, type)
73
- check_scan(s, /,(?: (?: J(\d+) ) | (\d+) | (?: M(\d+)\.(\d)\.(\d) ) )/x)
74
- julian_day_of_year = s[1]
75
- absolute_day_of_year = s[2]
76
- month = s[3]
77
- week = s[4]
78
- day_of_week = s[5]
79
-
80
- if s.scan(/\//)
81
- check_scan(s, /([-+]?\d+)(?::(\d+)(?::(\d+))?)?/)
82
- transition_at = get_seconds_after_midnight_from_hms(s[1], s[2], s[3])
83
- else
84
- transition_at = 7200
85
- end
86
-
87
- begin
88
- if julian_day_of_year
89
- JulianDayOfYearTransitionRule.new(julian_day_of_year.to_i, transition_at)
90
- elsif absolute_day_of_year
91
- AbsoluteDayOfYearTransitionRule.new(absolute_day_of_year.to_i, transition_at)
92
- elsif week == '5'
93
- LastDayOfMonthTransitionRule.new(month.to_i, day_of_week.to_i, transition_at)
94
- else
95
- DayOfMonthTransitionRule.new(month.to_i, week.to_i, day_of_week.to_i, transition_at)
96
- end
97
- rescue ArgumentError => e
98
- raise InvalidPosixTimeZone, "Invalid #{type} rule in POSIX-style time zone string: #{e}"
99
- end
100
- end
101
-
102
- # Returns an offset in seconds from hh:mm:ss values. The value can be
103
- # negative. -02:33:12 would represent 2 hours, 33 minutes and 12 seconds
104
- # ahead of UTC.
105
- def get_offset_from_hms(h, m, s)
106
- h = h.to_i
107
- m = m.to_i
108
- s = s.to_i
109
- raise InvalidPosixTimeZone, "Invalid minute #{m} in offset for POSIX-style time zone string." if m > 59
110
- raise InvalidPosixTimeZone, "Invalid second #{s} in offset for POSIX-style time zone string." if s > 59
111
- magnitude = (h.abs * 60 + m) * 60 + s
112
- h < 0 ? -magnitude : magnitude
113
- end
114
-
115
- # Returns the seconds from midnight from hh:mm:ss values. Hours can exceed
116
- # 24 for a time on the following day. Hours can be negative to subtract
117
- # hours from midnight on the given day. -02:33:12 represents 22:33:12 on
118
- # the prior day.
119
- def get_seconds_after_midnight_from_hms(h, m, s)
120
- h = h.to_i
121
- m = m.to_i
122
- s = s.to_i
123
- raise InvalidPosixTimeZone, "Invalid minute #{m} in time for POSIX-style time zone string." if m > 59
124
- raise InvalidPosixTimeZone, "Invalid second #{s} in time for POSIX-style time zone string." if s > 59
125
- (h * 3600) + m * 60 + s
126
- end
127
-
128
- # Scans for a pattern and raises an exception if the pattern does not
129
- # match the input.
130
- def check_scan(s, pattern)
131
- result = s.scan(pattern)
132
- raise InvalidPosixTimeZone, "Expected '#{s.rest}' to match #{pattern} in POSIX-style time zone string." unless result
133
- result
134
- end
135
- end
136
- end
@@ -1,176 +0,0 @@
1
- require 'date'
2
- require 'rational' unless defined?(Rational)
3
-
4
- module TZInfo
5
-
6
- # Methods to support different versions of Ruby.
7
- #
8
- # @private
9
- module RubyCoreSupport #:nodoc:
10
-
11
- # Use Rational.new! for performance reasons in Ruby 1.8.
12
- # This has been removed from 1.9, but Rational performs better.
13
- if Rational.respond_to? :new!
14
- def self.rational_new!(numerator, denominator = 1)
15
- Rational.new!(numerator, denominator)
16
- end
17
- else
18
- def self.rational_new!(numerator, denominator = 1)
19
- Rational(numerator, denominator)
20
- end
21
- end
22
-
23
- # Ruby 1.8.6 introduced new! and deprecated new0.
24
- # Ruby 1.9.0 removed new0.
25
- # Ruby trunk revision 31668 removed the new! method.
26
- # Still support new0 for better performance on older versions of Ruby (new0 indicates
27
- # that the rational has already been reduced to its lowest terms).
28
- # Fallback to jd with conversion from ajd if new! and new0 are unavailable.
29
- if DateTime.respond_to? :new!
30
- def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
31
- DateTime.new!(ajd, of, sg)
32
- end
33
- elsif DateTime.respond_to? :new0
34
- def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
35
- DateTime.new0(ajd, of, sg)
36
- end
37
- else
38
- HALF_DAYS_IN_DAY = rational_new!(1, 2)
39
-
40
- def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
41
- # Convert from an Astronomical Julian Day number to a civil Julian Day number.
42
- jd = ajd + of + HALF_DAYS_IN_DAY
43
-
44
- # Ruby trunk revision 31862 changed the behaviour of DateTime.jd so that it will no
45
- # longer accept a fractional civil Julian Day number if further arguments are specified.
46
- # Calculate the hours, minutes and seconds to pass to jd.
47
-
48
- jd_i = jd.to_i
49
- jd_i -= 1 if jd < 0
50
- hours = (jd - jd_i) * 24
51
- hours_i = hours.to_i
52
- minutes = (hours - hours_i) * 60
53
- minutes_i = minutes.to_i
54
- seconds = (minutes - minutes_i) * 60
55
-
56
- DateTime.jd(jd_i, hours_i, minutes_i, seconds, of, sg)
57
- end
58
- end
59
-
60
- # DateTime in Ruby 1.8.6 doesn't consider times within the 60th second to be
61
- # valid. When attempting to specify such a DateTime, subtract the fractional
62
- # part and then add it back later
63
- if Date.respond_to?(:valid_time?) && !Date.valid_time?(0, 0, rational_new!(59001, 1000)) # 0:0:59.001
64
- def self.datetime_new(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=Date::ITALY)
65
- if !s.kind_of?(Integer) && s > 59
66
- dt = DateTime.new(y, m, d, h, min, 59, of, sg)
67
- dt + (s - 59) / 86400
68
- else
69
- DateTime.new(y, m, d, h, min, s, of, sg)
70
- end
71
- end
72
- else
73
- def self.datetime_new(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=Date::ITALY)
74
- DateTime.new(y, m, d, h, min, s, of, sg)
75
- end
76
- end
77
-
78
- # Returns true if Time on the runtime platform supports Times defined
79
- # by negative 32-bit timestamps, otherwise false.
80
- begin
81
- Time.at(-1)
82
- Time.at(-2147483648)
83
-
84
- def self.time_supports_negative
85
- true
86
- end
87
- rescue ArgumentError
88
- def self.time_supports_negative
89
- false
90
- end
91
- end
92
-
93
- # Returns true if Time on the runtime platform supports Times defined by
94
- # 64-bit timestamps, otherwise false.
95
- begin
96
- Time.at(-2147483649)
97
- Time.at(2147483648)
98
-
99
- def self.time_supports_64bit
100
- true
101
- end
102
- rescue RangeError
103
- def self.time_supports_64bit
104
- false
105
- end
106
- end
107
-
108
- # Return the result of Time#nsec if it exists, otherwise return the
109
- # result of Time#usec * 1000.
110
- if Time.method_defined?(:nsec)
111
- def self.time_nsec(time)
112
- time.nsec
113
- end
114
- else
115
- def self.time_nsec(time)
116
- time.usec * 1000
117
- end
118
- end
119
-
120
- # Call String#force_encoding if this version of Ruby has encoding support
121
- # otherwise treat as a no-op.
122
- if String.method_defined?(:force_encoding)
123
- def self.force_encoding(str, encoding)
124
- str.force_encoding(encoding)
125
- end
126
- else
127
- def self.force_encoding(str, encoding)
128
- str
129
- end
130
- end
131
-
132
-
133
- # Wrapper for File.open that supports passing hash options for specifying
134
- # encodings on Ruby 1.9+. The options are ignored on earlier versions of
135
- # Ruby.
136
- if RUBY_VERSION =~ /\A1\.[0-8]\./
137
- def self.open_file(file_name, mode, opts, &block)
138
- File.open(file_name, mode, &block)
139
- end
140
- elsif RUBY_VERSION =~ /\A1\.9\./
141
- def self.open_file(file_name, mode, opts, &block)
142
- File.open(file_name, mode, opts, &block)
143
- end
144
- else
145
- # Evaluate method as a string because **opts isn't valid syntax prior to
146
- # Ruby 2.0.
147
- eval(<<-EOF
148
- def self.open_file(file_name, mode, opts, &block)
149
- File.open(file_name, mode, **opts, &block)
150
- end
151
- EOF
152
- )
153
- end
154
-
155
-
156
- # Object#untaint is deprecated and becomes a no-op in Ruby >= 2.7. It has
157
- # been removed from Ruby 3.2.
158
- if !Object.new.respond_to?(:untaint) || RUBY_VERSION =~ /\A(\d+)\.(\d+)(?:\.|\z)/ && ($1 == '2' && $2.to_i >= 7 || $1.to_i >= 3)
159
- # Returns the supplied `Object`
160
- #
161
- # @param o [Object] the `Object` to untaint.
162
- # @return [Object] `o`.
163
- def self.untaint(o)
164
- o
165
- end
166
- else
167
- # Untaints and returns the supplied `Object`.
168
- #
169
- # @param o [Object] the `Object` to untaint.
170
- # @return [Object] `o`.
171
- def self.untaint(o)
172
- o.untaint
173
- end
174
- end
175
- end
176
- end
@@ -1,74 +0,0 @@
1
- module TZInfo
2
- # Represents information about a country returned by RubyDataSource.
3
- #
4
- # @private
5
- class RubyCountryInfo < CountryInfo #:nodoc:
6
- # Constructs a new CountryInfo with an ISO 3166 country code, name and
7
- # block. The block will be evaluated to obtain the timezones for the
8
- # country when the zones are first needed.
9
- def initialize(code, name, &block)
10
- super(code, name)
11
- @block = block
12
- @zones = nil
13
- @zone_identifiers = nil
14
- end
15
-
16
- # Returns a frozen array of all the zone identifiers for the country. These
17
- # are in the order they were added using the timezone method.
18
- def zone_identifiers
19
- # Thread-safety: It is possible that the value of @zone_identifiers may be
20
- # calculated multiple times in concurrently executing threads. It is not
21
- # worth the overhead of locking to ensure that @zone_identifiers is only
22
- # calculated once.
23
-
24
- unless @zone_identifiers
25
- result = zones.collect {|zone| zone.identifier}.freeze
26
- return result if frozen?
27
- @zone_identifiers = result
28
- end
29
-
30
- @zone_identifiers
31
- end
32
-
33
- # Returns a frozen array of all the timezones for the for the country as
34
- # CountryTimezone instances. These are in the order they were added using
35
- # the timezone method.
36
- def zones
37
- # Thread-safety: It is possible that the value of @zones may be
38
- # calculated multiple times in concurrently executing threads. It is not
39
- # worth the overhead of locking to ensure that @zones is only
40
- # calculated once.
41
-
42
- unless @zones
43
- zones = Zones.new
44
- @block.call(zones) if @block
45
- result = zones.list.freeze
46
- return result if frozen?
47
- @block = nil
48
- @zones = result
49
- end
50
-
51
- @zones
52
- end
53
-
54
- # An instance of the Zones class is passed to the block used to define
55
- # timezones.
56
- #
57
- # @private
58
- class Zones #:nodoc:
59
- attr_reader :list
60
-
61
- def initialize
62
- @list = []
63
- end
64
-
65
- # Called by the index data to define a timezone for the country.
66
- def timezone(identifier, latitude_numerator, latitude_denominator,
67
- longitude_numerator, longitude_denominator, description = nil)
68
- @list << CountryTimezone.new!(identifier, latitude_numerator,
69
- latitude_denominator, longitude_numerator, longitude_denominator,
70
- description)
71
- end
72
- end
73
- end
74
- end
@@ -1,136 +0,0 @@
1
- module TZInfo
2
- # A DataSource that loads data from the set of Ruby modules included in the
3
- # TZInfo::Data library (tzinfo-data gem).
4
- #
5
- # To have TZInfo use this DataSource, call TZInfo::DataSource.set as follows:
6
- #
7
- # TZInfo::DataSource.set(:ruby)
8
- class RubyDataSource < DataSource
9
- # Whether the timezone index has been loaded yet.
10
- @@timezone_index_loaded = false
11
-
12
- # Whether the country index has been loaded yet.
13
- @@country_index_loaded = false
14
-
15
- # Initializes a new RubyDataSource instance.
16
- def initialize
17
- tzinfo_data = File.join('tzinfo', 'data')
18
- begin
19
- require(tzinfo_data)
20
-
21
- data_file = File.join('', 'tzinfo', 'data.rb')
22
- path = $".reverse_each.detect {|p| p.end_with?(data_file) }
23
- if path
24
- @base_path = RubyCoreSupport.untaint(File.join(File.dirname(path), 'data'))
25
- else
26
- @base_path = tzinfo_data
27
- end
28
- rescue LoadError
29
- @base_path = tzinfo_data
30
- end
31
- end
32
-
33
- # Returns a TimezoneInfo instance for a given identifier.
34
- # Raises InvalidTimezoneIdentifier if the timezone is not found or the
35
- # identifier is invalid.
36
- def load_timezone_info(identifier)
37
- raise InvalidTimezoneIdentifier, 'Invalid identifier' if identifier !~ /\A[A-Za-z0-9+\-_]+(\/[A-Za-z0-9+\-_]+)*\z/
38
-
39
- identifier = identifier.gsub(/-/, '__m__').gsub(/\+/, '__p__')
40
-
41
- # Untaint identifier after it has been reassigned to a new string. We
42
- # don't want to modify the original identifier. identifier may also be
43
- # frozen and therefore cannot be untainted.
44
- RubyCoreSupport.untaint(identifier)
45
-
46
- identifier = identifier.split('/')
47
- begin
48
- require_definition(identifier)
49
-
50
- m = Data::Definitions
51
- identifier.each {|part|
52
- m = m.const_get(part)
53
- }
54
-
55
- m.get
56
- rescue LoadError, NameError => e
57
- raise InvalidTimezoneIdentifier, e.message
58
- end
59
- end
60
-
61
- # Returns an array of all the available timezone identifiers.
62
- def timezone_identifiers
63
- load_timezone_index
64
- Data::Indexes::Timezones.timezones
65
- end
66
-
67
- # Returns an array of all the available timezone identifiers for
68
- # data timezones (i.e. those that actually contain definitions).
69
- def data_timezone_identifiers
70
- load_timezone_index
71
- Data::Indexes::Timezones.data_timezones
72
- end
73
-
74
- # Returns an array of all the available timezone identifiers that
75
- # are links to other timezones.
76
- def linked_timezone_identifiers
77
- load_timezone_index
78
- Data::Indexes::Timezones.linked_timezones
79
- end
80
-
81
- # Returns a CountryInfo instance for the given ISO 3166-1 alpha-2
82
- # country code. Raises InvalidCountryCode if the country could not be found
83
- # or the code is invalid.
84
- def load_country_info(code)
85
- load_country_index
86
- info = Data::Indexes::Countries.countries[code]
87
- raise InvalidCountryCode, 'Invalid country code' unless info
88
- info
89
- end
90
-
91
- # Returns an array of all the available ISO 3166-1 alpha-2
92
- # country codes.
93
- def country_codes
94
- load_country_index
95
- Data::Indexes::Countries.countries.keys.freeze
96
- end
97
-
98
- # Returns the name of this DataSource.
99
- def to_s
100
- "Ruby DataSource"
101
- end
102
-
103
- private
104
-
105
- # Requires a zone definition by its identifier (split on /).
106
- def require_definition(identifier)
107
- require_data(*(['definitions'] + identifier))
108
- end
109
-
110
- # Requires an index by its name.
111
- def require_index(name)
112
- require_data(*['indexes', name])
113
- end
114
-
115
- # Requires a file from tzinfo/data.
116
- def require_data(*file)
117
- require(File.join(@base_path, *file))
118
- end
119
-
120
- # Loads in the index of timezones if it hasn't already been loaded.
121
- def load_timezone_index
122
- unless @@timezone_index_loaded
123
- require_index('timezones')
124
- @@timezone_index_loaded = true
125
- end
126
- end
127
-
128
- # Loads in the index of countries if it hasn't already been loaded.
129
- def load_country_index
130
- unless @@country_index_loaded
131
- require_index('countries')
132
- @@country_index_loaded = true
133
- end
134
- end
135
- end
136
- end