tzinfo 1.2.4 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of tzinfo might be problematic. Click here for more details.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +20 -0
- data/LICENSE +1 -1
- data/README.md +3 -2
- data/lib/tzinfo/country_timezone.rb +14 -2
- data/lib/tzinfo/ruby_core_support.rb +31 -1
- data/lib/tzinfo/ruby_country_info.rb +6 -2
- data/lib/tzinfo/ruby_data_source.rb +22 -20
- data/lib/tzinfo/time_or_datetime.rb +12 -5
- data/lib/tzinfo/timezone.rb +8 -4
- data/lib/tzinfo/timezone_offset.rb +26 -3
- data/lib/tzinfo/timezone_period.rb +29 -5
- data/lib/tzinfo/timezone_proxy.rb +7 -1
- data/lib/tzinfo/timezone_transition.rb +12 -2
- data/lib/tzinfo/timezone_transition_definition.rb +6 -3
- data/lib/tzinfo/zoneinfo_country_info.rb +3 -1
- data/lib/tzinfo/zoneinfo_data_source.rb +8 -0
- data/lib/tzinfo/zoneinfo_timezone_info.rb +11 -7
- data/test/tc_country.rb +4 -4
- data/test/tc_country_timezone.rb +12 -0
- data/test/tc_ruby_country_info.rb +30 -0
- data/test/tc_ruby_data_source.rb +24 -2
- data/test/tc_time_or_datetime.rb +27 -6
- data/test/tc_timezone.rb +11 -2
- data/test/tc_timezone_period.rb +7 -0
- data/test/tc_timezone_proxy.rb +9 -0
- data/test/tc_timezone_transition.rb +14 -0
- data/test/tc_timezone_transition_definition.rb +11 -0
- data/test/tc_transition_data_timezone_info.rb +11 -1
- data/test/tc_zoneinfo_country_info.rb +14 -0
- data/test/tc_zoneinfo_data_source.rb +11 -2
- data/test/tc_zoneinfo_timezone_info.rb +106 -0
- data/test/test_utils.rb +59 -5
- data/test/ts_all_zoneinfo.rb +3 -1
- data/tzinfo.gemspec +1 -1
- data.tar.gz.sig +0 -0
- metadata +21 -23
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c204b46efe2fc4448fbb719bc143c031e71e5a5eaa21593cee6b04a8904b21f6
|
4
|
+
data.tar.gz: a70e08a0cb1ed9439ca48899e068e0455d2bf123601ef19db308cd9a39e156ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15ec7aefd75724e350d8f287d2b9af340af7e5916f6e535dd1d6673bbdeae2615992dd5b33181a354b400bce39fb054fd691d41453b335f5a527847eecfaf2b4
|
7
|
+
data.tar.gz: 6766a63a1a690944ef8ea3ac1ed9d5018216d1f139a1bbcddf99f00fa293bf56779b71bf2e27c80e0d4bf01cdcba375b3f6b5d046470324713a43e0747e0a9dd
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
Version 1.2.6 - 24-Dec-2019
|
2
|
+
---------------------------
|
3
|
+
|
4
|
+
* Timezone#strftime('%s', time) will now return the correct number of seconds
|
5
|
+
since the epoch. #91.
|
6
|
+
* Removed the unused TZInfo::RubyDataSource::REQUIRE_PATH constant.
|
7
|
+
* Fixed "SecurityError: Insecure operation - require" exceptions when loading
|
8
|
+
data with recent Ruby releases in safe mode.
|
9
|
+
* Fixed warnings when running on Ruby 2.7. #106 and #111.
|
10
|
+
|
11
|
+
|
12
|
+
Version 1.2.5 - 4-Feb-2018
|
13
|
+
--------------------------
|
14
|
+
|
15
|
+
* Support recursively (deep) freezing Country and Timezone instances. #80.
|
16
|
+
* Allow negative daylight savings time offsets to be derived when reading from
|
17
|
+
zoneinfo files. The utc_offset and std_offset are now derived correctly for
|
18
|
+
Europe/Dublin in the 2018a and 2018b releases of the Time Zone Database.
|
19
|
+
|
20
|
+
|
1
21
|
Version 1.2.4 - 26-Oct-2017
|
2
22
|
---------------------------
|
3
23
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -60,8 +60,9 @@ of `TZInfo::Timezone`) and convert a time in UTC to local New York time:
|
|
60
60
|
local = tz.utc_to_local(Time.utc(2005,8,29,15,35,0))
|
61
61
|
|
62
62
|
Note that the local Time returned will have a UTC timezone (`local.zone` will
|
63
|
-
return `"UTC"`). This is because the
|
64
|
-
UTC and the
|
63
|
+
return `"UTC"`). This is because the Time class in older (but still supported by
|
64
|
+
TZInfo) versions of Ruby can only handle two timezones: UTC and the system local
|
65
|
+
timezone.
|
65
66
|
|
66
67
|
To convert from a local time to UTC, the `local_to_utc` method can be used as
|
67
68
|
follows:
|
@@ -79,7 +79,13 @@ module TZInfo
|
|
79
79
|
# calculated multiple times in concurrently executing threads. It is not
|
80
80
|
# worth the overhead of locking to ensure that @latitude is only
|
81
81
|
# calculated once.
|
82
|
-
@latitude
|
82
|
+
unless @latitude
|
83
|
+
result = RubyCoreSupport.rational_new!(@latitude_numerator, @latitude_denominator)
|
84
|
+
return result if frozen?
|
85
|
+
@latitude = result
|
86
|
+
end
|
87
|
+
|
88
|
+
@latitude
|
83
89
|
end
|
84
90
|
|
85
91
|
# The longitude of this timezone in degrees as a Rational.
|
@@ -88,7 +94,13 @@ module TZInfo
|
|
88
94
|
# calculated multiple times in concurrently executing threads. It is not
|
89
95
|
# worth the overhead of locking to ensure that @longitude is only
|
90
96
|
# calculated once.
|
91
|
-
@longitude
|
97
|
+
unless @longitude
|
98
|
+
result = RubyCoreSupport.rational_new!(@longitude_numerator, @longitude_denominator)
|
99
|
+
return result if frozen?
|
100
|
+
@longitude = result
|
101
|
+
end
|
102
|
+
|
103
|
+
@longitude
|
92
104
|
end
|
93
105
|
|
94
106
|
# Returns true if and only if the given CountryTimezone is equal to the
|
@@ -137,10 +137,40 @@ module TZInfo
|
|
137
137
|
def self.open_file(file_name, mode, opts, &block)
|
138
138
|
File.open(file_name, mode, &block)
|
139
139
|
end
|
140
|
-
|
140
|
+
elsif RUBY_VERSION =~ /\A1\.9\./
|
141
141
|
def self.open_file(file_name, mode, opts, &block)
|
142
142
|
File.open(file_name, mode, opts, &block)
|
143
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 a deprecated no-op in Ruby >= 2.7 and will be removed in
|
157
|
+
# 3.0. Add a refinement to either silence the warning, or supply the method
|
158
|
+
# if needed.
|
159
|
+
old_verbose = $VERBOSE
|
160
|
+
$VERBOSE = false
|
161
|
+
begin
|
162
|
+
o = Object.new
|
163
|
+
if [:taint, :untaint, :tainted?].none? {|m| o.respond_to?(m) } || !o.taint.tainted?
|
164
|
+
module UntaintExt
|
165
|
+
refine Object do
|
166
|
+
def untaint
|
167
|
+
self
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
ensure
|
173
|
+
$VERBOSE = old_verbose
|
144
174
|
end
|
145
175
|
end
|
146
176
|
end
|
@@ -22,7 +22,9 @@ module TZInfo
|
|
22
22
|
# calculated once.
|
23
23
|
|
24
24
|
unless @zone_identifiers
|
25
|
-
|
25
|
+
result = zones.collect {|zone| zone.identifier}.freeze
|
26
|
+
return result if frozen?
|
27
|
+
@zone_identifiers = result
|
26
28
|
end
|
27
29
|
|
28
30
|
@zone_identifiers
|
@@ -40,8 +42,10 @@ module TZInfo
|
|
40
42
|
unless @zones
|
41
43
|
zones = Zones.new
|
42
44
|
@block.call(zones) if @block
|
45
|
+
result = zones.list.freeze
|
46
|
+
return result if frozen?
|
43
47
|
@block = nil
|
44
|
-
@zones =
|
48
|
+
@zones = result
|
45
49
|
end
|
46
50
|
|
47
51
|
@zones
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module TZInfo
|
2
|
+
using RubyCoreSupport::UntaintExt if RubyCoreSupport.const_defined?(:UntaintExt)
|
3
|
+
|
2
4
|
# A DataSource that loads data from the set of Ruby modules included in the
|
3
5
|
# TZInfo::Data library (tzinfo-data gem).
|
4
6
|
#
|
@@ -6,15 +8,30 @@ module TZInfo
|
|
6
8
|
#
|
7
9
|
# TZInfo::DataSource.set(:ruby)
|
8
10
|
class RubyDataSource < DataSource
|
9
|
-
# Base path for require.
|
10
|
-
REQUIRE_PATH = File.join('tzinfo', 'data', 'definitions')
|
11
|
-
|
12
11
|
# Whether the timezone index has been loaded yet.
|
13
12
|
@@timezone_index_loaded = false
|
14
13
|
|
15
14
|
# Whether the country index has been loaded yet.
|
16
15
|
@@country_index_loaded = false
|
17
16
|
|
17
|
+
# Initializes a new RubyDataSource instance.
|
18
|
+
def initialize
|
19
|
+
tzinfo_data = File.join('tzinfo', 'data')
|
20
|
+
begin
|
21
|
+
require(tzinfo_data)
|
22
|
+
|
23
|
+
data_file = File.join('', 'tzinfo', 'data.rb')
|
24
|
+
path = $".reverse_each.detect {|p| p.end_with?(data_file) }
|
25
|
+
if path
|
26
|
+
@base_path = File.join(File.dirname(path), 'data').untaint
|
27
|
+
else
|
28
|
+
@base_path = tzinfo_data
|
29
|
+
end
|
30
|
+
rescue LoadError
|
31
|
+
@base_path = tzinfo_data
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
18
35
|
# Returns a TimezoneInfo instance for a given identifier.
|
19
36
|
# Raises InvalidTimezoneIdentifier if the timezone is not found or the
|
20
37
|
# identifier is invalid.
|
@@ -93,27 +110,17 @@ module TZInfo
|
|
93
110
|
end
|
94
111
|
|
95
112
|
# Requires an index by its name.
|
96
|
-
def
|
113
|
+
def require_index(name)
|
97
114
|
require_data(*['indexes', name])
|
98
115
|
end
|
99
116
|
|
100
117
|
# Requires a file from tzinfo/data.
|
101
118
|
def require_data(*file)
|
102
|
-
|
103
|
-
end
|
104
|
-
|
105
|
-
# Requires a file from tzinfo/data.
|
106
|
-
def self.require_data(*file)
|
107
|
-
require File.join('tzinfo', 'data', *file)
|
119
|
+
require(File.join(@base_path, *file))
|
108
120
|
end
|
109
121
|
|
110
122
|
# Loads in the index of timezones if it hasn't already been loaded.
|
111
123
|
def load_timezone_index
|
112
|
-
self.class.load_timezone_index
|
113
|
-
end
|
114
|
-
|
115
|
-
# Loads in the index of timezones if it hasn't already been loaded.
|
116
|
-
def self.load_timezone_index
|
117
124
|
unless @@timezone_index_loaded
|
118
125
|
require_index('timezones')
|
119
126
|
@@timezone_index_loaded = true
|
@@ -122,11 +129,6 @@ module TZInfo
|
|
122
129
|
|
123
130
|
# Loads in the index of countries if it hasn't already been loaded.
|
124
131
|
def load_country_index
|
125
|
-
self.class.load_country_index
|
126
|
-
end
|
127
|
-
|
128
|
-
# Loads in the index of countries if it hasn't already been loaded.
|
129
|
-
def self.load_country_index
|
130
132
|
unless @@country_index_loaded
|
131
133
|
require_index('countries')
|
132
134
|
@@country_index_loaded = true
|
@@ -54,11 +54,14 @@ module TZInfo
|
|
54
54
|
# calculated once.
|
55
55
|
|
56
56
|
unless @time
|
57
|
-
if @timestamp
|
58
|
-
|
57
|
+
result = if @timestamp
|
58
|
+
Time.at(@timestamp).utc
|
59
59
|
else
|
60
|
-
|
60
|
+
Time.utc(year, mon, mday, hour, min, sec, usec)
|
61
61
|
end
|
62
|
+
|
63
|
+
return result if frozen?
|
64
|
+
@time = result
|
62
65
|
end
|
63
66
|
|
64
67
|
@time
|
@@ -78,7 +81,9 @@ module TZInfo
|
|
78
81
|
# Avoid using Rational unless necessary.
|
79
82
|
u = usec
|
80
83
|
s = u == 0 ? sec : Rational(sec * 1000000 + u, 1000000)
|
81
|
-
|
84
|
+
result = RubyCoreSupport.datetime_new(year, mon, mday, hour, min, s)
|
85
|
+
return result if frozen?
|
86
|
+
@datetime = result
|
82
87
|
end
|
83
88
|
|
84
89
|
@datetime
|
@@ -92,7 +97,9 @@ module TZInfo
|
|
92
97
|
# calculated once.
|
93
98
|
|
94
99
|
unless @timestamp
|
95
|
-
|
100
|
+
result = to_time.to_i
|
101
|
+
return result if frozen?
|
102
|
+
@timestamp = result
|
96
103
|
end
|
97
104
|
|
98
105
|
@timestamp
|
data/lib/tzinfo/timezone.rb
CHANGED
@@ -571,17 +571,21 @@ module TZInfo
|
|
571
571
|
# version 2.0.0, %z will be passed to Time#strftime and DateTime#strftime
|
572
572
|
# instead. Some of the formatting options may cease to be available
|
573
573
|
# depending on the version of Ruby in use (for example, %:::z is only
|
574
|
-
# supported by Time#strftime from MRI version 2.0.0 onwards.
|
574
|
+
# supported by Time#strftime from MRI version 2.0.0 onwards).
|
575
575
|
def strftime(format, utc = Time.now.utc)
|
576
|
+
utc = TimeOrDateTime.wrap(utc)
|
576
577
|
period = period_for_utc(utc)
|
577
|
-
|
578
|
-
local =
|
578
|
+
local_wrapped = period.to_local(utc)
|
579
|
+
local = local_wrapped.to_orig
|
580
|
+
local = local_wrapped.to_time unless local.kind_of?(Time) || local.kind_of?(DateTime)
|
579
581
|
abbreviation = period.abbreviation.to_s.gsub(/%/, '%%')
|
580
582
|
|
581
|
-
format = format.gsub(/%(%*)(
|
583
|
+
format = format.gsub(/%(%*)([sZ]|:*z)/) do
|
582
584
|
if $1.length.odd?
|
583
585
|
# Escaped literal percent or series of percents. Pass on to strftime.
|
584
586
|
"#$1%#$2"
|
587
|
+
elsif $2 == "s"
|
588
|
+
"#$1#{utc.to_i}"
|
585
589
|
elsif $2 == "Z"
|
586
590
|
"#$1#{abbreviation}"
|
587
591
|
else
|
@@ -1,11 +1,34 @@
|
|
1
1
|
module TZInfo
|
2
2
|
# Represents an offset defined in a Timezone data file.
|
3
3
|
class TimezoneOffset
|
4
|
-
# The base offset of the timezone from UTC in seconds.
|
4
|
+
# The base offset of the timezone from UTC in seconds. This does not include
|
5
|
+
# any adjustment made for daylight savings time and will typically remain
|
6
|
+
# constant throughout the year.
|
7
|
+
#
|
8
|
+
# To obtain the currently observed offset from UTC, including the effect of
|
9
|
+
# daylight savings time, use utc_total_offset instead.
|
10
|
+
#
|
11
|
+
# Note that zoneinfo files only include the value of utc_total_offset and a
|
12
|
+
# DST flag. When using ZoneinfoDataSource, the utc_offset will be derived
|
13
|
+
# from changes to the UTC total offset and the DST flag. As a consequence,
|
14
|
+
# utc_total_offset will always be correct, but utc_offset may be inaccurate.
|
15
|
+
#
|
16
|
+
# If you require utc_offset to be accurate, install the tzinfo-data gem and
|
17
|
+
# set RubyDataSource as the DataSource.
|
5
18
|
attr_reader :utc_offset
|
6
19
|
|
7
|
-
# The offset from
|
8
|
-
# daylight savings is
|
20
|
+
# The offset from the time zone's standard time in seconds. Zero
|
21
|
+
# when daylight savings time is not in effect. Non-zero (usually 3600 = 1
|
22
|
+
# hour) if daylight savings is being observed.
|
23
|
+
#
|
24
|
+
# Note that zoneinfo files only include the value of utc_total_offset and
|
25
|
+
# a DST flag. When using DataSources::ZoneinfoDataSource, the std_offset
|
26
|
+
# will be derived from changes to the UTC total offset and the DST flag. As
|
27
|
+
# a consequence, utc_total_offset will always be correct, but std_offset
|
28
|
+
# may be inaccurate.
|
29
|
+
#
|
30
|
+
# If you require std_offset to be accurate, install the tzinfo-data gem
|
31
|
+
# and set RubyDataSource as the DataSource.
|
9
32
|
attr_reader :std_offset
|
10
33
|
|
11
34
|
# The total offset of this observance from UTC in seconds
|
@@ -38,14 +38,36 @@ module TZInfo
|
|
38
38
|
@utc_total_offset_rational = nil
|
39
39
|
end
|
40
40
|
|
41
|
-
#
|
41
|
+
# The base offset of the timezone from UTC in seconds. This does not include
|
42
|
+
# any adjustment made for daylight savings time and will typically remain
|
43
|
+
# constant throughout the year.
|
44
|
+
#
|
45
|
+
# To obtain the currently observed offset from UTC, including the effect of
|
46
|
+
# daylight savings time, use utc_total_offset instead.
|
47
|
+
#
|
48
|
+
# Note that zoneinfo files only include the value of utc_total_offset and a
|
49
|
+
# DST flag. When using ZoneinfoDataSource, the utc_offset will be derived
|
50
|
+
# from changes to the UTC total offset and the DST flag. As a consequence,
|
51
|
+
# utc_total_offset will always be correct, but utc_offset may be inaccurate.
|
52
|
+
#
|
53
|
+
# If you require utc_offset to be accurate, install the tzinfo-data gem and
|
54
|
+
# set RubyDataSource as the DataSource.
|
42
55
|
def utc_offset
|
43
56
|
@offset.utc_offset
|
44
57
|
end
|
45
58
|
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
59
|
+
# The offset from the time zone's standard time in seconds. Zero
|
60
|
+
# when daylight savings time is not in effect. Non-zero (usually 3600 = 1
|
61
|
+
# hour) if daylight savings is being observed.
|
62
|
+
#
|
63
|
+
# Note that zoneinfo files only include the value of utc_total_offset and
|
64
|
+
# a DST flag. When using DataSources::ZoneinfoDataSource, the std_offset
|
65
|
+
# will be derived from changes to the UTC total offset and the DST flag. As
|
66
|
+
# a consequence, utc_total_offset will always be correct, but std_offset
|
67
|
+
# may be inaccurate.
|
68
|
+
#
|
69
|
+
# If you require std_offset to be accurate, install the tzinfo-data gem
|
70
|
+
# and set RubyDataSource as the DataSource.
|
49
71
|
def std_offset
|
50
72
|
@offset.std_offset
|
51
73
|
end
|
@@ -71,7 +93,9 @@ module TZInfo
|
|
71
93
|
# to ensure that @zone_identifiers is only calculated once.
|
72
94
|
|
73
95
|
unless @utc_total_offset_rational
|
74
|
-
|
96
|
+
result = OffsetRationals.rational_for_offset(utc_total_offset)
|
97
|
+
return result if frozen?
|
98
|
+
@utc_total_offset_rational = result
|
75
99
|
end
|
76
100
|
@utc_total_offset_rational
|
77
101
|
end
|
@@ -93,7 +93,13 @@ module TZInfo
|
|
93
93
|
# calculated multiple times in concurrently executing threads. It is not
|
94
94
|
# worth the overhead of locking to ensure that @real_timezone is only
|
95
95
|
# calculated once.
|
96
|
-
@real_timezone
|
96
|
+
unless @real_timezone
|
97
|
+
result = Timezone.get(@identifier)
|
98
|
+
return result if frozen?
|
99
|
+
@real_timezone = result
|
100
|
+
end
|
101
|
+
|
102
|
+
@real_timezone
|
97
103
|
end
|
98
104
|
end
|
99
105
|
end
|
@@ -43,7 +43,12 @@ module TZInfo
|
|
43
43
|
# worth the overhead of locking to ensure that @local_end_at is only
|
44
44
|
# calculated once.
|
45
45
|
|
46
|
-
|
46
|
+
unless @local_end_at
|
47
|
+
result = at.add_with_convert(@previous_offset.utc_total_offset)
|
48
|
+
return result if frozen?
|
49
|
+
@local_end_at = result
|
50
|
+
end
|
51
|
+
|
47
52
|
@local_end_at
|
48
53
|
end
|
49
54
|
|
@@ -67,7 +72,12 @@ module TZInfo
|
|
67
72
|
# worth the overhead of locking to ensure that @local_start_at is only
|
68
73
|
# calculated once.
|
69
74
|
|
70
|
-
|
75
|
+
unless @local_start_at
|
76
|
+
result = at.add_with_convert(@offset.utc_total_offset)
|
77
|
+
return result if frozen?
|
78
|
+
@local_start_at = result
|
79
|
+
end
|
80
|
+
|
71
81
|
@local_start_at
|
72
82
|
end
|
73
83
|
|
@@ -71,13 +71,16 @@ module TZInfo
|
|
71
71
|
# overhead of locking to ensure that @at is only calculated once.
|
72
72
|
|
73
73
|
unless @at
|
74
|
-
unless @denominator
|
75
|
-
|
74
|
+
result = unless @denominator
|
75
|
+
TimeOrDateTime.new(@numerator_or_time)
|
76
76
|
else
|
77
77
|
r = RubyCoreSupport.rational_new!(@numerator_or_time, @denominator)
|
78
78
|
dt = RubyCoreSupport.datetime_new!(r, 0, Date::ITALY)
|
79
|
-
|
79
|
+
TimeOrDateTime.new(dt)
|
80
80
|
end
|
81
|
+
|
82
|
+
return result if frozen?
|
83
|
+
@at = result
|
81
84
|
end
|
82
85
|
|
83
86
|
@at
|
@@ -20,7 +20,9 @@ module TZInfo
|
|
20
20
|
# calculated once.
|
21
21
|
|
22
22
|
unless @zone_identifiers
|
23
|
-
|
23
|
+
result = zones.collect {|zone| zone.identifier}.freeze
|
24
|
+
return result if frozen?
|
25
|
+
@zone_identifiers = result
|
24
26
|
end
|
25
27
|
|
26
28
|
@zone_identifiers
|
@@ -1,4 +1,12 @@
|
|
1
1
|
module TZInfo
|
2
|
+
# Use send as a workaround for an issue on JRuby 9.2.9.0 where using the
|
3
|
+
# refinement causes calls to RubyCoreSupport.file_open to fail to pass the
|
4
|
+
# block parameter.
|
5
|
+
#
|
6
|
+
# https://travis-ci.org/tzinfo/tzinfo/jobs/628812051#L1931
|
7
|
+
# https://github.com/jruby/jruby/issues/6009
|
8
|
+
send(:using, TZInfo::RubyCoreSupport::UntaintExt) if TZInfo::RubyCoreSupport.const_defined?(:UntaintExt)
|
9
|
+
|
2
10
|
# An InvalidZoneinfoDirectory exception is raised if the DataSource is
|
3
11
|
# set to a specific zoneinfo path, which is not a valid zoneinfo directory
|
4
12
|
# (i.e. a directory containing index files named iso3166.tab and zone.tab
|
@@ -1,4 +1,6 @@
|
|
1
1
|
module TZInfo
|
2
|
+
using RubyCoreSupport::UntaintExt if RubyCoreSupport.const_defined?(:UntaintExt)
|
3
|
+
|
2
4
|
# An InvalidZoneinfoFile exception is raised if an attempt is made to load an
|
3
5
|
# invalid zoneinfo file.
|
4
6
|
class InvalidZoneinfoFile < StandardError
|
@@ -93,19 +95,21 @@ module TZInfo
|
|
93
95
|
if offset[:is_dst]
|
94
96
|
utc_offset_from_next = transition[:utc_offset_from_next]
|
95
97
|
|
96
|
-
difference_to_previous = utc_total_offset - (utc_offset_from_previous || utc_total_offset)
|
97
|
-
difference_to_next = utc_total_offset - (utc_offset_from_next || utc_total_offset)
|
98
|
+
difference_to_previous = (utc_total_offset - (utc_offset_from_previous || utc_total_offset)).abs
|
99
|
+
difference_to_next = (utc_total_offset - (utc_offset_from_next || utc_total_offset)).abs
|
98
100
|
|
99
|
-
utc_offset = if difference_to_previous
|
101
|
+
utc_offset = if difference_to_previous == 3600
|
102
|
+
utc_offset_from_previous
|
103
|
+
elsif difference_to_next == 3600
|
104
|
+
utc_offset_from_next
|
105
|
+
elsif difference_to_previous > 0 && difference_to_next > 0
|
100
106
|
difference_to_previous < difference_to_next ? utc_offset_from_previous : utc_offset_from_next
|
101
107
|
elsif difference_to_previous > 0
|
102
108
|
utc_offset_from_previous
|
103
109
|
elsif difference_to_next > 0
|
104
110
|
utc_offset_from_next
|
105
|
-
else
|
106
|
-
#
|
107
|
-
# relative to both the previous and next used base utc offset, or
|
108
|
-
# there are no non-DST offsets. Assume a 1 hour offset from base.
|
111
|
+
else
|
112
|
+
# No difference, assume a 1 hour offset from standard time.
|
109
113
|
utc_total_offset - 3600
|
110
114
|
end
|
111
115
|
|
data/test/tc_country.rb
CHANGED
@@ -2,6 +2,8 @@ require File.join(File.expand_path(File.dirname(__FILE__)), 'test_utils')
|
|
2
2
|
|
3
3
|
include TZInfo
|
4
4
|
|
5
|
+
using TaintExt if Module.const_defined?(:TaintExt)
|
6
|
+
|
5
7
|
class TCCountry < Minitest::Test
|
6
8
|
def setup
|
7
9
|
@orig_data_source = DataSource.get
|
@@ -46,7 +48,7 @@ class TCCountry < Minitest::Test
|
|
46
48
|
def test_get_tainted_loaded
|
47
49
|
Country.get('GB')
|
48
50
|
|
49
|
-
safe_test do
|
51
|
+
safe_test(:unavailable => :skip) do
|
50
52
|
code = 'GB'.dup.taint
|
51
53
|
assert(code.tainted?)
|
52
54
|
country = Country.get(code)
|
@@ -65,7 +67,7 @@ class TCCountry < Minitest::Test
|
|
65
67
|
end
|
66
68
|
|
67
69
|
def test_get_tainted_not_previously_loaded
|
68
|
-
safe_test do
|
70
|
+
safe_test(:unavailable => :skip) do
|
69
71
|
code = 'GB'.dup.taint
|
70
72
|
assert(code.tainted?)
|
71
73
|
country = Country.get(code)
|
@@ -190,7 +192,6 @@ class TCCountry < Minitest::Test
|
|
190
192
|
# If country gets reloaded for some reason, it needs to force a reload of
|
191
193
|
# the country index.
|
192
194
|
|
193
|
-
c = Country.get('US')
|
194
195
|
assert_equal('US', Country.get('US').code)
|
195
196
|
|
196
197
|
# Suppress redefined method warnings.
|
@@ -198,7 +199,6 @@ class TCCountry < Minitest::Test
|
|
198
199
|
load 'tzinfo/country.rb'
|
199
200
|
end
|
200
201
|
|
201
|
-
c = Country.get('US')
|
202
202
|
assert_equal('US', Country.get('US').code)
|
203
203
|
end
|
204
204
|
|
data/test/tc_country_timezone.rb
CHANGED
@@ -17,6 +17,12 @@ class TCCountryTimezone < Minitest::Test
|
|
17
17
|
ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
|
18
18
|
assert_equal(Rational(2059, 40), ct.latitude)
|
19
19
|
end
|
20
|
+
|
21
|
+
def test_latitude_after_freeze_new!
|
22
|
+
ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
|
23
|
+
ct.freeze
|
24
|
+
assert_equal(Rational(2059, 40), ct.latitude)
|
25
|
+
end
|
20
26
|
|
21
27
|
def test_latitude_new
|
22
28
|
ct = CountryTimezone.new('Europe/London', Rational(2059, 40), Rational(-5, 16))
|
@@ -27,6 +33,12 @@ class TCCountryTimezone < Minitest::Test
|
|
27
33
|
ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
|
28
34
|
assert_equal(Rational(-5, 16), ct.longitude)
|
29
35
|
end
|
36
|
+
|
37
|
+
def test_longitude_after_freeze_new!
|
38
|
+
ct = CountryTimezone.new!('Europe/London', 2059, 40, -5, 16)
|
39
|
+
ct.freeze
|
40
|
+
assert_equal(Rational(-5, 16), ct.longitude)
|
41
|
+
end
|
30
42
|
|
31
43
|
def test_longitude_new
|
32
44
|
ct = CountryTimezone.new('Europe/London', Rational(2059, 40), Rational(-5, 16))
|
@@ -37,6 +37,19 @@ class TCRubyCountryInfo < Minitest::Test
|
|
37
37
|
assert_equal(['ZZ/TimezoneB', 'ZZ/TimezoneA', 'ZZ/TimezoneC', 'ZZ/TimezoneD'], ci.zone_identifiers)
|
38
38
|
assert(ci.zone_identifiers.frozen?)
|
39
39
|
end
|
40
|
+
|
41
|
+
def test_zone_identifiers_after_freeze
|
42
|
+
ci = RubyCountryInfo.new('ZZ', 'Zzz') do |c|
|
43
|
+
c.timezone('ZZ/TimezoneB', 1, 2, 1, 2, 'Timezone B')
|
44
|
+
c.timezone('ZZ/TimezoneA', 1, 4, 1, 4, 'Timezone A')
|
45
|
+
c.timezone('ZZ/TimezoneC', -10, 3, -20, 7, 'C')
|
46
|
+
c.timezone('ZZ/TimezoneD', -10, 3, -20, 7)
|
47
|
+
end
|
48
|
+
|
49
|
+
ci.freeze
|
50
|
+
|
51
|
+
assert_equal(['ZZ/TimezoneB', 'ZZ/TimezoneA', 'ZZ/TimezoneC', 'ZZ/TimezoneD'], ci.zone_identifiers)
|
52
|
+
end
|
40
53
|
|
41
54
|
def test_zones_empty
|
42
55
|
ci = RubyCountryInfo.new('ZZ', 'Zzz') {|c| }
|
@@ -65,6 +78,23 @@ class TCRubyCountryInfo < Minitest::Test
|
|
65
78
|
ci.zones)
|
66
79
|
assert(ci.zones.frozen?)
|
67
80
|
end
|
81
|
+
|
82
|
+
def test_zones_after_freeze
|
83
|
+
ci = RubyCountryInfo.new('ZZ', 'Zzz') do |c|
|
84
|
+
c.timezone('ZZ/TimezoneB', 1, 2, 1, 2, 'Timezone B')
|
85
|
+
c.timezone('ZZ/TimezoneA', 1, 4, 1, 4, 'Timezone A')
|
86
|
+
c.timezone('ZZ/TimezoneC', -10, 3, -20, 7, 'C')
|
87
|
+
c.timezone('ZZ/TimezoneD', -10, 3, -20, 7)
|
88
|
+
end
|
89
|
+
|
90
|
+
ci.freeze
|
91
|
+
|
92
|
+
assert_equal([CountryTimezone.new!('ZZ/TimezoneB', 1, 2, 1, 2, 'Timezone B'),
|
93
|
+
CountryTimezone.new!('ZZ/TimezoneA', 1, 4, 1, 4, 'Timezone A'),
|
94
|
+
CountryTimezone.new!('ZZ/TimezoneC', -10, 3, -20, 7, 'C'),
|
95
|
+
CountryTimezone.new!('ZZ/TimezoneD', -10, 3, -20, 7)],
|
96
|
+
ci.zones)
|
97
|
+
end
|
68
98
|
|
69
99
|
def test_deferred_evaluate
|
70
100
|
block_called = false
|