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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.yardopts +3 -0
- data/CHANGES.md +469 -431
- data/LICENSE +13 -13
- data/README.md +368 -114
- data/lib/tzinfo/country.rb +131 -129
- data/lib/tzinfo/country_timezone.rb +70 -112
- data/lib/tzinfo/data_source.rb +389 -144
- data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
- data/lib/tzinfo/data_sources/country_info.rb +42 -0
- data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
- data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
- data/lib/tzinfo/data_sources/ruby_data_source.rb +141 -0
- data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
- data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
- data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +573 -0
- data/lib/tzinfo/data_sources/zoneinfo_reader.rb +284 -0
- data/lib/tzinfo/data_sources.rb +8 -0
- data/lib/tzinfo/data_timezone.rb +33 -47
- data/lib/tzinfo/datetime_with_offset.rb +153 -0
- data/lib/tzinfo/format1/country_definer.rb +17 -0
- data/lib/tzinfo/format1/country_index_definition.rb +64 -0
- data/lib/tzinfo/format1/timezone_definer.rb +64 -0
- data/lib/tzinfo/format1/timezone_definition.rb +39 -0
- data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
- data/lib/tzinfo/format1.rb +10 -0
- data/lib/tzinfo/format2/country_definer.rb +68 -0
- data/lib/tzinfo/format2/country_index_definer.rb +68 -0
- data/lib/tzinfo/format2/country_index_definition.rb +46 -0
- data/lib/tzinfo/format2/timezone_definer.rb +94 -0
- data/lib/tzinfo/format2/timezone_definition.rb +73 -0
- data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
- data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
- data/lib/tzinfo/format2.rb +10 -0
- data/lib/tzinfo/info_timezone.rb +26 -21
- data/lib/tzinfo/linked_timezone.rb +33 -52
- data/lib/tzinfo/offset_timezone_period.rb +42 -0
- data/lib/tzinfo/string_deduper.rb +118 -0
- data/lib/tzinfo/time_with_offset.rb +128 -0
- data/lib/tzinfo/timestamp.rb +548 -0
- data/lib/tzinfo/timestamp_with_offset.rb +85 -0
- data/lib/tzinfo/timezone.rb +979 -502
- data/lib/tzinfo/timezone_offset.rb +84 -74
- data/lib/tzinfo/timezone_period.rb +151 -217
- data/lib/tzinfo/timezone_proxy.rb +70 -79
- data/lib/tzinfo/timezone_transition.rb +77 -109
- data/lib/tzinfo/transitions_timezone_period.rb +63 -0
- data/lib/tzinfo/version.rb +7 -0
- data/lib/tzinfo/with_offset.rb +61 -0
- data/lib/tzinfo.rb +60 -40
- data.tar.gz.sig +0 -0
- metadata +51 -115
- metadata.gz.sig +2 -3
- data/Rakefile +0 -107
- data/lib/tzinfo/annual_rules.rb +0 -51
- data/lib/tzinfo/country_index_definition.rb +0 -31
- data/lib/tzinfo/country_info.rb +0 -42
- data/lib/tzinfo/data_timezone_info.rb +0 -55
- data/lib/tzinfo/linked_timezone_info.rb +0 -26
- data/lib/tzinfo/offset_rationals.rb +0 -77
- data/lib/tzinfo/posix_time_zone_parser.rb +0 -136
- data/lib/tzinfo/ruby_core_support.rb +0 -176
- data/lib/tzinfo/ruby_country_info.rb +0 -74
- data/lib/tzinfo/ruby_data_source.rb +0 -136
- data/lib/tzinfo/time_or_datetime.rb +0 -351
- data/lib/tzinfo/timezone_definition.rb +0 -36
- data/lib/tzinfo/timezone_index_definition.rb +0 -54
- data/lib/tzinfo/timezone_info.rb +0 -30
- data/lib/tzinfo/timezone_transition_definition.rb +0 -104
- data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
- data/lib/tzinfo/transition_rule.rb +0 -325
- data/lib/tzinfo/zoneinfo_country_info.rb +0 -37
- data/lib/tzinfo/zoneinfo_data_source.rb +0 -504
- data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -516
- data/test/assets/payload.rb +0 -1
- data/test/tc_annual_rules.rb +0 -95
- data/test/tc_country.rb +0 -240
- data/test/tc_country_index_definition.rb +0 -69
- data/test/tc_country_info.rb +0 -16
- data/test/tc_country_timezone.rb +0 -173
- data/test/tc_data_source.rb +0 -218
- data/test/tc_data_timezone.rb +0 -99
- data/test/tc_data_timezone_info.rb +0 -18
- data/test/tc_info_timezone.rb +0 -34
- data/test/tc_linked_timezone.rb +0 -155
- data/test/tc_linked_timezone_info.rb +0 -23
- data/test/tc_offset_rationals.rb +0 -23
- data/test/tc_posix_time_zone_parser.rb +0 -261
- data/test/tc_ruby_core_support.rb +0 -168
- data/test/tc_ruby_country_info.rb +0 -110
- data/test/tc_ruby_data_source.rb +0 -175
- data/test/tc_time_or_datetime.rb +0 -674
- data/test/tc_timezone.rb +0 -1361
- data/test/tc_timezone_definition.rb +0 -113
- data/test/tc_timezone_index_definition.rb +0 -73
- data/test/tc_timezone_info.rb +0 -11
- data/test/tc_timezone_london.rb +0 -143
- data/test/tc_timezone_melbourne.rb +0 -142
- data/test/tc_timezone_new_york.rb +0 -142
- data/test/tc_timezone_offset.rb +0 -126
- data/test/tc_timezone_period.rb +0 -555
- data/test/tc_timezone_proxy.rb +0 -136
- data/test/tc_timezone_transition.rb +0 -366
- data/test/tc_timezone_transition_definition.rb +0 -295
- data/test/tc_timezone_utc.rb +0 -27
- data/test/tc_transition_data_timezone_info.rb +0 -433
- data/test/tc_transition_rule.rb +0 -663
- data/test/tc_zoneinfo_country_info.rb +0 -78
- data/test/tc_zoneinfo_data_source.rb +0 -1226
- data/test/tc_zoneinfo_timezone_info.rb +0 -2149
- data/test/test_utils.rb +0 -214
- data/test/ts_all.rb +0 -7
- data/test/ts_all_ruby.rb +0 -5
- data/test/ts_all_zoneinfo.rb +0 -9
- data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
- data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -327
- data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -230
- data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -273
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -198
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -333
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -277
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -235
- data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
- data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -940
- data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -609
- data/test/tzinfo-data/tzinfo/data/version.rb +0 -20
- data/test/tzinfo-data/tzinfo/data.rb +0 -8
- data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
- data/test/zoneinfo/America/New_York +0 -0
- data/test/zoneinfo/Australia/Melbourne +0 -0
- data/test/zoneinfo/EST +0 -0
- data/test/zoneinfo/Etc/UTC +0 -0
- data/test/zoneinfo/Europe/Amsterdam +0 -0
- data/test/zoneinfo/Europe/Andorra +0 -0
- data/test/zoneinfo/Europe/London +0 -0
- data/test/zoneinfo/Europe/Paris +0 -0
- data/test/zoneinfo/Europe/Prague +0 -0
- data/test/zoneinfo/Factory +0 -0
- data/test/zoneinfo/iso3166.tab +0 -274
- data/test/zoneinfo/leapseconds +0 -78
- data/test/zoneinfo/posix/Europe/London +0 -0
- data/test/zoneinfo/posixrules +0 -0
- data/test/zoneinfo/right/Europe/London +0 -0
- data/test/zoneinfo/zone.tab +0 -452
- data/test/zoneinfo/zone1970.tab +0 -384
- 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
|