tzinfo 2.0.2 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +105 -0
- data/LICENSE +1 -1
- data/README.md +4 -4
- data/lib/tzinfo/annual_rules.rb +71 -0
- data/lib/tzinfo/data_source.rb +11 -0
- data/lib/tzinfo/data_sources/posix_time_zone_parser.rb +181 -0
- data/lib/tzinfo/data_sources/ruby_data_source.rb +2 -2
- data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +29 -10
- data/lib/tzinfo/data_sources/zoneinfo_reader.rb +205 -7
- data/lib/tzinfo/time_with_offset.rb +26 -0
- data/lib/tzinfo/timestamp.rb +18 -14
- data/lib/tzinfo/transition_rule.rb +455 -0
- data/lib/tzinfo/version.rb +1 -1
- data/lib/tzinfo.rb +15 -0
- data.tar.gz.sig +0 -0
- metadata +12 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f5b3120678f9251533f0c044814f666142eb5538412c92c06aa66719251f474
|
4
|
+
data.tar.gz: a837074505ff48d553506e1eeb4eac8e3148cc6aa48e996e552d4d9bde1ef614
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f9f43bcf636bc1c3311cc3d417a951dfeb7cc697ad37add1b6b4bbbb0caa0a7226da508ca5c5521d1cf122254ded7ecd4b1da7f6240121dc311b1706c15119d1
|
7
|
+
data.tar.gz: 48314ac805148665c326cc450e2dc96582bb26a2ecc58d97234252c866a162f4f60d2495b6ddaaf3f7b3bd27190d9db452159d58ae57505463a836ce097b5acc
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGES.md
CHANGED
@@ -1,5 +1,37 @@
|
|
1
1
|
# Changes
|
2
2
|
|
3
|
+
## Version 2.0.5 - 19-Jul-2022
|
4
|
+
|
5
|
+
* Changed `DateTime` results to always use the proleptic Gregorian calendar.
|
6
|
+
This affects `DateTime` results prior to 1582-10-15 and any arithmetic
|
7
|
+
performed on the results that would produce a secondary result prior to
|
8
|
+
1582-10-15.
|
9
|
+
* Added support for eager loading all the time zone and country data by calling
|
10
|
+
either `TZInfo::DataSource#eager_load!` or `TZInfo.eager_load!`. Compatible
|
11
|
+
with Ruby On Rails' `eager_load_namespaces`. #129.
|
12
|
+
* Ignore the SECURITY file from Arch Linux's tzdata package. #134.
|
13
|
+
|
14
|
+
|
15
|
+
## Version 2.0.4 - 16-Dec-2020
|
16
|
+
|
17
|
+
* Fixed an incorrect `InvalidTimezoneIdentifier` exception raised when loading a
|
18
|
+
zoneinfo file that includes rules specifying an additional transition to the
|
19
|
+
final defined offset (for example, Africa/Casablanca in version 2018e of the
|
20
|
+
Time Zone Database). #123.
|
21
|
+
|
22
|
+
|
23
|
+
## Version 2.0.3 - 8-Nov-2020
|
24
|
+
|
25
|
+
* Added support for handling "slim" format zoneinfo files that are produced by
|
26
|
+
default by zic version 2020b and later. The POSIX-style TZ string is now used
|
27
|
+
calculate DST transition times after the final defined transition in the file.
|
28
|
+
#120.
|
29
|
+
* Fixed `TimeWithOffset#getlocal` returning a `TimeWithOffset` with the
|
30
|
+
`timezone_offset` still assigned when called with an offset argument on JRuby
|
31
|
+
9.3.
|
32
|
+
* Rubinius is no longer supported.
|
33
|
+
|
34
|
+
|
3
35
|
## Version 2.0.2 - 2-Apr-2020
|
4
36
|
|
5
37
|
* Fixed 'wrong number of arguments' errors when running on JRuby 9.0. #114.
|
@@ -162,6 +194,33 @@
|
|
162
194
|
`TZInfo::Country.get('US').zone_identifiers` should be used instead.
|
163
195
|
|
164
196
|
|
197
|
+
## Version 1.2.10 - 19-Jul-2022
|
198
|
+
|
199
|
+
* Fixed a relative path traversal bug that could cause arbitrary files to be
|
200
|
+
loaded with `require` when used with `RubyDataSource`. Please refer to
|
201
|
+
<https://github.com/tzinfo/tzinfo/security/advisories/GHSA-5cm2-9h8c-rvfx> for
|
202
|
+
details. CVE-2022-31163.
|
203
|
+
* Ignore the SECURITY file from Arch Linux's tzdata package. #134.
|
204
|
+
|
205
|
+
|
206
|
+
## Version 1.2.9 - 16-Dec-2020
|
207
|
+
|
208
|
+
* Fixed an incorrect `InvalidTimezoneIdentifier` exception raised when loading a
|
209
|
+
zoneinfo file that includes rules specifying an additional transition to the
|
210
|
+
final defined offset (for example, Africa/Casablanca in version 2018e of the
|
211
|
+
Time Zone Database). #123.
|
212
|
+
|
213
|
+
|
214
|
+
## Version 1.2.8 - 8-Nov-2020
|
215
|
+
|
216
|
+
* Added support for handling "slim" format zoneinfo files that are produced by
|
217
|
+
default by zic version 2020b and later. The POSIX-style TZ string is now used
|
218
|
+
calculate DST transition times after the final defined transition in the file.
|
219
|
+
The 64-bit section is now always used regardless of whether Time has support
|
220
|
+
for 64-bit times. #120.
|
221
|
+
* Rubinius is no longer supported.
|
222
|
+
|
223
|
+
|
165
224
|
## Version 1.2.7 - 2-Apr-2020
|
166
225
|
|
167
226
|
* Fixed 'wrong number of arguments' errors when running on JRuby 9.0. #114.
|
@@ -302,6 +361,52 @@
|
|
302
361
|
use other `TimezonePeriod` instance methods instead (issue #7655).
|
303
362
|
|
304
363
|
|
364
|
+
## Version 0.3.61 (tzdata v2022a) - 19-Jul-2022
|
365
|
+
|
366
|
+
* Fixed a relative path traversal bug that could cause arbitrary files to be
|
367
|
+
loaded with `require` from the Ruby load path. Please refer to
|
368
|
+
<https://github.com/tzinfo/tzinfo/security/advisories/GHSA-5cm2-9h8c-rvfx> for
|
369
|
+
details. CVE-2022-31163.
|
370
|
+
* Updated to tzdata version 2022a
|
371
|
+
(<https://mm.icann.org/pipermail/tz-announce/2022-March/000070.html>).
|
372
|
+
|
373
|
+
|
374
|
+
## Version 0.3.60 (tzdata v2021a) - 6-Feb-2021
|
375
|
+
|
376
|
+
* Updated to tzdata version 2021a
|
377
|
+
(<https://mm.icann.org/pipermail/tz-announce/2021-January/000065.html>).
|
378
|
+
|
379
|
+
|
380
|
+
## Version 0.3.59 (tzdata v2020e) - 24-Dec-2020
|
381
|
+
|
382
|
+
* Updated to tzdata version 2020e
|
383
|
+
(<https://mm.icann.org/pipermail/tz-announce/2020-December/000063.html>).
|
384
|
+
|
385
|
+
|
386
|
+
## Version 0.3.58 (tzdata v2020d) - 8-Nov-2020
|
387
|
+
|
388
|
+
* Updated to tzdata version 2020d
|
389
|
+
(<https://mm.icann.org/pipermail/tz-announce/2020-October/000062.html>).
|
390
|
+
|
391
|
+
|
392
|
+
## Version 0.3.57 (tzdata v2020a) - 17-May-2020
|
393
|
+
|
394
|
+
* Updated to tzdata version 2020a
|
395
|
+
(<https://mm.icann.org/pipermail/tz-announce/2020-April/000058.html>).
|
396
|
+
|
397
|
+
|
398
|
+
## Version 0.3.56 (tzdata v2019c) - 1-Nov-2019
|
399
|
+
|
400
|
+
* Updated to tzdata version 2019c
|
401
|
+
(<https://mm.icann.org/pipermail/tz-announce/2019-September/000057.html>).
|
402
|
+
|
403
|
+
|
404
|
+
## Version 0.3.55 (tzdata v2018g) - 27-Oct-2018
|
405
|
+
|
406
|
+
* Updated to tzdata version 2018g
|
407
|
+
(<https://mm.icann.org/pipermail/tz-announce/2018-October/000052.html>).
|
408
|
+
|
409
|
+
|
305
410
|
## Version 0.3.54 (tzdata v2018d) - 25-Mar-2018
|
306
411
|
|
307
412
|
* Updated to tzdata version 2018d
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# TZInfo - Ruby Time Zone Library
|
2
2
|
|
3
|
-
[![RubyGems](https://img.shields.io/gem/v/tzinfo)](https://rubygems.org/gems/tzinfo) [![
|
3
|
+
[![RubyGems](https://img.shields.io/gem/v/tzinfo?logo=rubygems&label=Gem)](https://rubygems.org/gems/tzinfo) [![Tests](https://github.com/tzinfo/tzinfo/workflows/Tests/badge.svg?branch=master&event=push)](https://github.com/tzinfo/tzinfo/actions?query=workflow%3ATests+branch%3Amaster+event%3Apush)
|
4
4
|
|
5
5
|
[TZInfo](https://tzinfo.github.io) is a Ruby library that provides access to
|
6
6
|
time zone data and allows times to be converted using time zone rules.
|
@@ -36,7 +36,7 @@ documentation for further details.
|
|
36
36
|
## Installation
|
37
37
|
|
38
38
|
The TZInfo gem can be installed by running `gem install tzinfo` or by adding
|
39
|
-
|
39
|
+
`gem 'tzinfo'` to your `Gemfile` and running `bundle install`.
|
40
40
|
|
41
41
|
To use the Ruby modules as the data source, TZInfo::Data will also need to be
|
42
42
|
installed by running `gem install tzinfo-data` or by adding `gem 'tzinfo-data'`
|
@@ -368,8 +368,8 @@ claims.
|
|
368
368
|
|
369
369
|
## Compatibility
|
370
370
|
|
371
|
-
TZInfo v2.0.0 requires a minimum of Ruby MRI 1.9.3
|
372
|
-
later)
|
371
|
+
TZInfo v2.0.0 requires a minimum of Ruby MRI 1.9.3 or JRuby 1.7 (in 1.9 mode or
|
372
|
+
later).
|
373
373
|
|
374
374
|
|
375
375
|
## Thread-Safety
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module TZInfo
|
5
|
+
# A set of rules that define when transitions occur in time zones with
|
6
|
+
# annually occurring daylight savings time.
|
7
|
+
#
|
8
|
+
# @private
|
9
|
+
class AnnualRules #:nodoc:
|
10
|
+
# @return [TimezoneOffset] the standard offset that applies when daylight
|
11
|
+
# savings time is not in force.
|
12
|
+
attr_reader :std_offset
|
13
|
+
|
14
|
+
# @return [TimezoneOffset] the offset that applies when daylight savings
|
15
|
+
# time is in force.
|
16
|
+
attr_reader :dst_offset
|
17
|
+
|
18
|
+
# @return [TransitionRule] the rule that determines when daylight savings
|
19
|
+
# time starts.
|
20
|
+
attr_reader :dst_start_rule
|
21
|
+
|
22
|
+
# @return [TransitionRule] the rule that determines when daylight savings
|
23
|
+
# time ends.
|
24
|
+
attr_reader :dst_end_rule
|
25
|
+
|
26
|
+
# Initializes a new {AnnualRules} instance.
|
27
|
+
#
|
28
|
+
# @param std_offset [TimezoneOffset] the standard offset that applies when
|
29
|
+
# daylight savings time is not in force.
|
30
|
+
# @param dst_offset [TimezoneOffset] the offset that applies when daylight
|
31
|
+
# savings time is in force.
|
32
|
+
# @param dst_start_rule [TransitionRule] the rule that determines when
|
33
|
+
# daylight savings time starts.
|
34
|
+
# @param dst_end_rule [TransitionRule] the rule that determines when daylight
|
35
|
+
# savings time ends.
|
36
|
+
def initialize(std_offset, dst_offset, dst_start_rule, dst_end_rule)
|
37
|
+
@std_offset = std_offset
|
38
|
+
@dst_offset = dst_offset
|
39
|
+
@dst_start_rule = dst_start_rule
|
40
|
+
@dst_end_rule = dst_end_rule
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the transitions between standard and daylight savings time for a
|
44
|
+
# given year. The results are ordered by time of occurrence (earliest to
|
45
|
+
# latest).
|
46
|
+
#
|
47
|
+
# @param year [Integer] the year to calculate transitions for.
|
48
|
+
# @return [Array<TimezoneTransition>] the transitions for the year.
|
49
|
+
def transitions(year)
|
50
|
+
start_dst = apply_rule(@dst_start_rule, @std_offset, @dst_offset, year)
|
51
|
+
end_dst = apply_rule(@dst_end_rule, @dst_offset, @std_offset, year)
|
52
|
+
|
53
|
+
end_dst.timestamp_value < start_dst.timestamp_value ? [end_dst, start_dst] : [start_dst, end_dst]
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Applies a given rule between offsets on a year.
|
59
|
+
#
|
60
|
+
# @param rule [TransitionRule] the rule to apply.
|
61
|
+
# @param from_offset [TimezoneOffset] the offset the rule transitions from.
|
62
|
+
# @param to_offset [TimezoneOffset] the offset the rule transitions to.
|
63
|
+
# @param year [Integer] the year when the transition occurs.
|
64
|
+
# @return [TimezoneTransition] the transition determined by the rule.
|
65
|
+
def apply_rule(rule, from_offset, to_offset, year)
|
66
|
+
at = rule.at(from_offset, year)
|
67
|
+
TimezoneTransition.new(to_offset, from_offset, at.value)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
private_constant :AnnualRules
|
71
|
+
end
|
data/lib/tzinfo/data_source.rb
CHANGED
@@ -247,6 +247,17 @@ module TZInfo
|
|
247
247
|
raise_invalid_data_source('country_codes')
|
248
248
|
end
|
249
249
|
|
250
|
+
# Loads all timezone and country data into memory.
|
251
|
+
#
|
252
|
+
# This may be desirable in production environments to improve copy-on-write
|
253
|
+
# performance and to avoid flushing the constant cache every time a new
|
254
|
+
# timezone or country is loaded from {DataSources::RubyDataSource}.
|
255
|
+
def eager_load!
|
256
|
+
timezone_identifiers.each {|identifier| load_timezone_info(identifier) }
|
257
|
+
country_codes.each {|code| load_country_info(code) }
|
258
|
+
nil
|
259
|
+
end
|
260
|
+
|
250
261
|
# @return [String] a description of the {DataSource}.
|
251
262
|
def to_s
|
252
263
|
"Default DataSource"
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'strscan'
|
5
|
+
|
6
|
+
module TZInfo
|
7
|
+
# Use send as a workaround for erroneous 'wrong number of arguments' errors
|
8
|
+
# with JRuby 9.0.5.0 when calling methods with Java implementations. See #114.
|
9
|
+
send(:using, UntaintExt) if TZInfo.const_defined?(:UntaintExt)
|
10
|
+
|
11
|
+
module DataSources
|
12
|
+
# An {InvalidPosixTimeZone} exception is raised if an invalid POSIX-style
|
13
|
+
# time zone string is encountered.
|
14
|
+
#
|
15
|
+
# @private
|
16
|
+
class InvalidPosixTimeZone < StandardError #:nodoc:
|
17
|
+
end
|
18
|
+
private_constant :InvalidPosixTimeZone
|
19
|
+
|
20
|
+
# A parser for POSIX-style TZ strings used in zoneinfo files and specified
|
21
|
+
# by tzfile.5 and tzset.3.
|
22
|
+
#
|
23
|
+
# @private
|
24
|
+
class PosixTimeZoneParser #:nodoc:
|
25
|
+
# Initializes a new {PosixTimeZoneParser}.
|
26
|
+
#
|
27
|
+
# @param string_deduper [StringDeduper] a {StringDeduper} instance to use
|
28
|
+
# to dedupe abbreviations.
|
29
|
+
def initialize(string_deduper)
|
30
|
+
@string_deduper = string_deduper
|
31
|
+
end
|
32
|
+
|
33
|
+
# Parses a POSIX-style TZ string.
|
34
|
+
#
|
35
|
+
# @param tz_string [String] the string to parse.
|
36
|
+
# @return [Object] either a {TimezoneOffset} for a constantly applied
|
37
|
+
# offset or an {AnnualRules} instance representing the rules.
|
38
|
+
# @raise [InvalidPosixTimeZone] if `tz_string` is not a `String`.
|
39
|
+
# @raise [InvalidPosixTimeZone] if `tz_string` is is not valid.
|
40
|
+
def parse(tz_string)
|
41
|
+
raise InvalidPosixTimeZone unless tz_string.kind_of?(String)
|
42
|
+
return nil if tz_string.empty?
|
43
|
+
|
44
|
+
s = StringScanner.new(tz_string)
|
45
|
+
check_scan(s, /([^-+,\d<][^-+,\d]*) | <([^>]+)>/x)
|
46
|
+
std_abbrev = @string_deduper.dedupe((s[1] || s[2]).untaint)
|
47
|
+
check_scan(s, /([-+]?\d+)(?::(\d+)(?::(\d+))?)?/)
|
48
|
+
std_offset = get_offset_from_hms(s[1], s[2], s[3])
|
49
|
+
|
50
|
+
if s.scan(/([^-+,\d<][^-+,\d]*) | <([^>]+)>/x)
|
51
|
+
dst_abbrev = @string_deduper.dedupe((s[1] || s[2]).untaint)
|
52
|
+
|
53
|
+
if s.scan(/([-+]?\d+)(?::(\d+)(?::(\d+))?)?/)
|
54
|
+
dst_offset = get_offset_from_hms(s[1], s[2], s[3])
|
55
|
+
else
|
56
|
+
# POSIX is negative for ahead of UTC.
|
57
|
+
dst_offset = std_offset - 3600
|
58
|
+
end
|
59
|
+
|
60
|
+
dst_difference = std_offset - dst_offset
|
61
|
+
|
62
|
+
start_rule = parse_rule(s, 'start')
|
63
|
+
end_rule = parse_rule(s, 'end')
|
64
|
+
|
65
|
+
raise InvalidPosixTimeZone, "Expected the end of a POSIX-style time zone string but found '#{s.rest}'." if s.rest?
|
66
|
+
|
67
|
+
if start_rule.is_always_first_day_of_year? && start_rule.transition_at == 0 &&
|
68
|
+
end_rule.is_always_last_day_of_year? && end_rule.transition_at == 86400 + dst_difference
|
69
|
+
# Constant daylight savings time.
|
70
|
+
# POSIX is negative for ahead of UTC.
|
71
|
+
TimezoneOffset.new(-std_offset, dst_difference, dst_abbrev)
|
72
|
+
else
|
73
|
+
AnnualRules.new(
|
74
|
+
TimezoneOffset.new(-std_offset, 0, std_abbrev),
|
75
|
+
TimezoneOffset.new(-std_offset, dst_difference, dst_abbrev),
|
76
|
+
start_rule,
|
77
|
+
end_rule)
|
78
|
+
end
|
79
|
+
elsif !s.rest?
|
80
|
+
# Constant standard time.
|
81
|
+
# POSIX is negative for ahead of UTC.
|
82
|
+
TimezoneOffset.new(-std_offset, 0, std_abbrev)
|
83
|
+
else
|
84
|
+
raise InvalidPosixTimeZone, "Expected the end of a POSIX-style time zone string but found '#{s.rest}'."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
# Parses a rule.
|
91
|
+
#
|
92
|
+
# @param s [StringScanner] the `StringScanner` to read the rule from.
|
93
|
+
# @param type [String] the type of rule (either `'start'` or `'end'`).
|
94
|
+
# @raise [InvalidPosixTimeZone] if the rule is not valid.
|
95
|
+
# @return [TransitionRule] the parsed rule.
|
96
|
+
def parse_rule(s, type)
|
97
|
+
check_scan(s, /,(?: (?: J(\d+) ) | (\d+) | (?: M(\d+)\.(\d)\.(\d) ) )/x)
|
98
|
+
julian_day_of_year = s[1]
|
99
|
+
absolute_day_of_year = s[2]
|
100
|
+
month = s[3]
|
101
|
+
week = s[4]
|
102
|
+
day_of_week = s[5]
|
103
|
+
|
104
|
+
if s.scan(/\//)
|
105
|
+
check_scan(s, /([-+]?\d+)(?::(\d+)(?::(\d+))?)?/)
|
106
|
+
transition_at = get_seconds_after_midnight_from_hms(s[1], s[2], s[3])
|
107
|
+
else
|
108
|
+
transition_at = 7200
|
109
|
+
end
|
110
|
+
|
111
|
+
begin
|
112
|
+
if julian_day_of_year
|
113
|
+
JulianDayOfYearTransitionRule.new(julian_day_of_year.to_i, transition_at)
|
114
|
+
elsif absolute_day_of_year
|
115
|
+
AbsoluteDayOfYearTransitionRule.new(absolute_day_of_year.to_i, transition_at)
|
116
|
+
elsif week == '5'
|
117
|
+
LastDayOfMonthTransitionRule.new(month.to_i, day_of_week.to_i, transition_at)
|
118
|
+
else
|
119
|
+
DayOfMonthTransitionRule.new(month.to_i, week.to_i, day_of_week.to_i, transition_at)
|
120
|
+
end
|
121
|
+
rescue ArgumentError => e
|
122
|
+
raise InvalidPosixTimeZone, "Invalid #{type} rule in POSIX-style time zone string: #{e}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns an offset in seconds from hh:mm:ss values. The value can be
|
127
|
+
# negative. -02:33:12 would represent 2 hours, 33 minutes and 12 seconds
|
128
|
+
# ahead of UTC.
|
129
|
+
#
|
130
|
+
# @param h [String] the hours.
|
131
|
+
# @param m [String] the minutes.
|
132
|
+
# @param s [String] the seconds.
|
133
|
+
# @return [Integer] the offset.
|
134
|
+
# @raise [InvalidPosixTimeZone] if the mm and ss values are greater than
|
135
|
+
# 59.
|
136
|
+
def get_offset_from_hms(h, m, s)
|
137
|
+
h = h.to_i
|
138
|
+
m = m.to_i
|
139
|
+
s = s.to_i
|
140
|
+
raise InvalidPosixTimeZone, "Invalid minute #{m} in offset for POSIX-style time zone string." if m > 59
|
141
|
+
raise InvalidPosixTimeZone, "Invalid second #{s} in offset for POSIX-style time zone string." if s > 59
|
142
|
+
magnitude = (h.abs * 60 + m) * 60 + s
|
143
|
+
h < 0 ? -magnitude : magnitude
|
144
|
+
end
|
145
|
+
|
146
|
+
# Returns the seconds from midnight from hh:mm:ss values. Hours can exceed
|
147
|
+
# 24 for a time on the following day. Hours can be negative to subtract
|
148
|
+
# hours from midnight on the given day. -02:33:12 represents 22:33:12 on
|
149
|
+
# the prior day.
|
150
|
+
#
|
151
|
+
# @param h [String] the hour.
|
152
|
+
# @param m [String] the minutes past the hour.
|
153
|
+
# @param s [String] the seconds past the minute.
|
154
|
+
# @return [Integer] the number of seconds after midnight.
|
155
|
+
# @raise [InvalidPosixTimeZone] if the mm and ss values are greater than
|
156
|
+
# 59.
|
157
|
+
def get_seconds_after_midnight_from_hms(h, m, s)
|
158
|
+
h = h.to_i
|
159
|
+
m = m.to_i
|
160
|
+
s = s.to_i
|
161
|
+
raise InvalidPosixTimeZone, "Invalid minute #{m} in time for POSIX-style time zone string." if m > 59
|
162
|
+
raise InvalidPosixTimeZone, "Invalid second #{s} in time for POSIX-style time zone string." if s > 59
|
163
|
+
(h * 3600) + m * 60 + s
|
164
|
+
end
|
165
|
+
|
166
|
+
# Scans for a pattern and raises an exception if the pattern does not
|
167
|
+
# match the input.
|
168
|
+
#
|
169
|
+
# @param s [StringScanner] the `StringScanner` to scan.
|
170
|
+
# @param pattern [Regexp] the pattern to match.
|
171
|
+
# @return [String] the result of the scan.
|
172
|
+
# @raise [InvalidPosixTimeZone] if the pattern does not match the input.
|
173
|
+
def check_scan(s, pattern)
|
174
|
+
result = s.scan(pattern)
|
175
|
+
raise InvalidPosixTimeZone, "Expected '#{s.rest}' to match #{pattern} in POSIX-style time zone string." unless result
|
176
|
+
result
|
177
|
+
end
|
178
|
+
end
|
179
|
+
private_constant :PosixTimeZoneParser
|
180
|
+
end
|
181
|
+
end
|
@@ -116,14 +116,14 @@ module TZInfo
|
|
116
116
|
# @param identifier [Array<string>] the component parts of a time zone
|
117
117
|
# identifier (split on /). This must have already been validated.
|
118
118
|
def require_definition(identifier)
|
119
|
-
require_data(
|
119
|
+
require_data('definitions', *identifier)
|
120
120
|
end
|
121
121
|
|
122
122
|
# Requires an index by its name.
|
123
123
|
#
|
124
124
|
# @param name [String] an index name.
|
125
125
|
def require_index(name)
|
126
|
-
require_data(
|
126
|
+
require_data('indexes', name)
|
127
127
|
end
|
128
128
|
|
129
129
|
# Requires a file from tzinfo/data.
|
@@ -78,6 +78,30 @@ module TZInfo
|
|
78
78
|
DEFAULT_ALTERNATE_ISO3166_TAB_SEARCH_PATH = ['/usr/share/misc/iso3166.tab', '/usr/share/misc/iso3166'].freeze
|
79
79
|
private_constant :DEFAULT_ALTERNATE_ISO3166_TAB_SEARCH_PATH
|
80
80
|
|
81
|
+
# Files and directories in the top level zoneinfo directory that will be
|
82
|
+
# excluded from the list of available time zones:
|
83
|
+
#
|
84
|
+
# - +VERSION is included on Mac OS X.
|
85
|
+
# - leapseconds is a list of leap seconds.
|
86
|
+
# - localtime is the current local timezone (may be a link).
|
87
|
+
# - posix, posixrules and right are directories containing other
|
88
|
+
# versions of the zoneinfo files.
|
89
|
+
# - SECURITY is included in the Arch Linux tzdata package.
|
90
|
+
# - src is a directory containing the tzdata source included on Solaris.
|
91
|
+
# - timeconfig is a symlink included on Slackware.
|
92
|
+
EXCLUDED_FILENAMES = [
|
93
|
+
'+VERSION',
|
94
|
+
'leapseconds',
|
95
|
+
'localtime',
|
96
|
+
'posix',
|
97
|
+
'posixrules',
|
98
|
+
'right',
|
99
|
+
'SECURITY',
|
100
|
+
'src',
|
101
|
+
'timeconfig'
|
102
|
+
].freeze
|
103
|
+
private_constant :EXCLUDED_FILENAMES
|
104
|
+
|
81
105
|
# Paths to be checked to find the system zoneinfo directory.
|
82
106
|
#
|
83
107
|
# @private
|
@@ -237,7 +261,10 @@ module TZInfo
|
|
237
261
|
@timezone_identifiers = load_timezone_identifiers.freeze
|
238
262
|
@countries = load_countries(iso3166_tab_path, zone_tab_path).freeze
|
239
263
|
@country_codes = @countries.keys.sort!.freeze
|
240
|
-
|
264
|
+
|
265
|
+
string_deduper = ConcurrentStringDeduper.new
|
266
|
+
posix_tz_parser = PosixTimeZoneParser.new(string_deduper)
|
267
|
+
@zoneinfo_reader = ZoneinfoReader.new(posix_tz_parser, string_deduper)
|
241
268
|
end
|
242
269
|
|
243
270
|
# Returns a frozen `Array` of all the available time zone identifiers. The
|
@@ -391,15 +418,7 @@ module TZInfo
|
|
391
418
|
def load_timezone_identifiers
|
392
419
|
index = []
|
393
420
|
|
394
|
-
|
395
|
-
# +VERSION is included on Mac OS X.
|
396
|
-
# leapseconds is a list of leap seconds.
|
397
|
-
# localtime is the current local timezone (may be a link).
|
398
|
-
# posix, posixrules and right are directories containing other versions of the zoneinfo files.
|
399
|
-
# src is a directory containing the tzdata source included on Solaris.
|
400
|
-
# timeconfig is a symlink included on Slackware.
|
401
|
-
|
402
|
-
enum_timezones([], ['+VERSION', 'leapseconds', 'localtime', 'posix', 'posixrules', 'right', 'src', 'timeconfig']) do |identifier|
|
421
|
+
enum_timezones([], EXCLUDED_FILENAMES) do |identifier|
|
403
422
|
index << identifier.join('/').freeze
|
404
423
|
end
|
405
424
|
|