tzinfo 1.2.5 → 1.2.9
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 +4 -4
- checksums.yaml.gz.sig +3 -3
- data.tar.gz.sig +0 -0
- data/CHANGES.md +86 -48
- data/LICENSE +1 -1
- data/README.md +9 -8
- data/lib/tzinfo.rb +3 -0
- data/lib/tzinfo/annual_rules.rb +51 -0
- data/lib/tzinfo/data_source.rb +1 -1
- data/lib/tzinfo/posix_time_zone_parser.rb +136 -0
- data/lib/tzinfo/ruby_core_support.rb +24 -1
- data/lib/tzinfo/ruby_data_source.rb +24 -20
- data/lib/tzinfo/time_or_datetime.rb +11 -0
- data/lib/tzinfo/timezone.rb +10 -6
- data/lib/tzinfo/transition_rule.rb +325 -0
- data/lib/tzinfo/zoneinfo_data_source.rb +10 -1
- data/lib/tzinfo/zoneinfo_timezone_info.rb +264 -40
- data/test/tc_annual_rules.rb +95 -0
- data/test/tc_country.rb +6 -2
- data/test/tc_posix_time_zone_parser.rb +261 -0
- data/test/tc_ruby_data_source.rb +26 -2
- data/test/tc_time_or_datetime.rb +26 -6
- data/test/tc_timezone.rb +13 -2
- data/test/tc_transition_data_timezone_info.rb +11 -1
- data/test/tc_transition_rule.rb +663 -0
- data/test/tc_zoneinfo_data_source.rb +11 -2
- data/test/tc_zoneinfo_timezone_info.rb +1034 -113
- data/test/test_utils.rb +32 -3
- data/test/ts_all_zoneinfo.rb +3 -1
- data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +5 -5
- data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +13 -1
- data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +13 -1
- data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +1 -1
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +2 -2
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +2 -2
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +1 -1
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +15 -3
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +13 -1
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +13 -1
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +15 -3
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +19 -4
- data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +1 -1
- data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +197 -184
- data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +60 -47
- data/test/tzinfo-data/tzinfo/data/version.rb +9 -3
- 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 +13 -14
- data/test/zoneinfo/leapseconds +38 -21
- 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 +172 -159
- data/test/zoneinfo/zone1970.tab +185 -170
- data/tzinfo.gemspec +2 -2
- metadata +28 -24
- metadata.gz.sig +0 -0
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
TZInfo - Ruby Timezone Library
|
2
2
|
==============================
|
3
3
|
|
4
|
-
[![
|
4
|
+
[![RubyGems](https://img.shields.io/gem/v/tzinfo)](https://rubygems.org/gems/tzinfo) [![Travis CI Build](https://img.shields.io/travis/com/tzinfo/tzinfo/1.2?logo=travis)](https://travis-ci.com/tzinfo/tzinfo) [![AppVeyor Build](https://img.shields.io/appveyor/build/philr/tzinfo/1.2?logo=appveyor)](https://ci.appveyor.com/project/philr/tzinfo/branch/1.2)
|
5
5
|
|
6
|
-
[TZInfo](
|
6
|
+
[TZInfo](https://tzinfo.github.io) provides daylight savings aware
|
7
7
|
transformations between times in different timezones.
|
8
8
|
|
9
9
|
|
@@ -13,10 +13,10 @@ Data Sources
|
|
13
13
|
TZInfo requires a source of timezone data. There are two built-in options:
|
14
14
|
|
15
15
|
1. The TZInfo::Data library (the tzinfo-data gem). TZInfo::Data contains a set
|
16
|
-
of Ruby modules that are generated from the [IANA Time Zone Database](
|
16
|
+
of Ruby modules that are generated from the [IANA Time Zone Database](https://www.iana.org/time-zones).
|
17
17
|
2. A zoneinfo directory. Most Unix-like systems include a zoneinfo directory
|
18
18
|
containing timezone definitions. These are also generated from the
|
19
|
-
[IANA Time Zone Database](
|
19
|
+
[IANA Time Zone Database](https://www.iana.org/time-zones).
|
20
20
|
|
21
21
|
By default, TZInfo::Data will be used. If TZInfo::Data is not available (i.e.
|
22
22
|
if `require 'tzinfo/data'` fails), then TZInfo will search for a zoneinfo
|
@@ -25,7 +25,7 @@ directory instead (using the search path specified by
|
|
25
25
|
|
26
26
|
If no data source can be found, a `TZInfo::DataSourceNotFound` exception will be
|
27
27
|
raised when TZInfo is used. Further information is available
|
28
|
-
[in the wiki](
|
28
|
+
[in the wiki](https://tzinfo.github.io/datasourcenotfound) to help with
|
29
29
|
resolving `TZInfo::DataSourceNotFound` errors.
|
30
30
|
|
31
31
|
The default data source selection can be overridden using
|
@@ -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:
|
@@ -129,7 +130,7 @@ thread boundaries.
|
|
129
130
|
Documentation
|
130
131
|
-------------
|
131
132
|
|
132
|
-
API documentation for TZInfo is available on [RubyDoc.info](
|
133
|
+
API documentation for TZInfo is available on [RubyDoc.info](https://rubydoc.info/gems/tzinfo/frames).
|
133
134
|
|
134
135
|
|
135
136
|
License
|
data/lib/tzinfo.rb
CHANGED
@@ -10,6 +10,8 @@ require 'tzinfo/timezone_definition'
|
|
10
10
|
|
11
11
|
require 'tzinfo/timezone_offset'
|
12
12
|
require 'tzinfo/timezone_transition'
|
13
|
+
require 'tzinfo/transition_rule'
|
14
|
+
require 'tzinfo/annual_rules'
|
13
15
|
require 'tzinfo/timezone_transition_definition'
|
14
16
|
|
15
17
|
require 'tzinfo/timezone_index_definition'
|
@@ -22,6 +24,7 @@ require 'tzinfo/zoneinfo_timezone_info'
|
|
22
24
|
|
23
25
|
require 'tzinfo/data_source'
|
24
26
|
require 'tzinfo/ruby_data_source'
|
27
|
+
require 'tzinfo/posix_time_zone_parser'
|
25
28
|
require 'tzinfo/zoneinfo_data_source'
|
26
29
|
|
27
30
|
require 'tzinfo/timezone_period'
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module TZInfo
|
2
|
+
# A set of rules that define when transitions occur in time zones with
|
3
|
+
# annually occurring daylight savings time.
|
4
|
+
#
|
5
|
+
# @private
|
6
|
+
class AnnualRules #:nodoc:
|
7
|
+
# Returned by #transitions. #offset is the TimezoneOffset that applies
|
8
|
+
# from the UTC TimeOrDateTime #at. #previous_offset is the prior
|
9
|
+
# TimezoneOffset.
|
10
|
+
Transition = Struct.new(:offset, :previous_offset, :at)
|
11
|
+
|
12
|
+
# The standard offset that applies when daylight savings time is not in
|
13
|
+
# force.
|
14
|
+
attr_reader :std_offset
|
15
|
+
|
16
|
+
# The offset that applies when daylight savings time is in force.
|
17
|
+
attr_reader :dst_offset
|
18
|
+
|
19
|
+
# The rule that determines when daylight savings time starts.
|
20
|
+
attr_reader :dst_start_rule
|
21
|
+
|
22
|
+
# The rule that determines when daylight savings time ends.
|
23
|
+
attr_reader :dst_end_rule
|
24
|
+
|
25
|
+
# Initializes a new {AnnualRules} instance.
|
26
|
+
def initialize(std_offset, dst_offset, dst_start_rule, dst_end_rule)
|
27
|
+
@std_offset = std_offset
|
28
|
+
@dst_offset = dst_offset
|
29
|
+
@dst_start_rule = dst_start_rule
|
30
|
+
@dst_end_rule = dst_end_rule
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns the transitions between standard and daylight savings time for a
|
34
|
+
# given year. The results are ordered by time of occurrence (earliest to
|
35
|
+
# latest).
|
36
|
+
def transitions(year)
|
37
|
+
start_dst = apply_rule(@dst_start_rule, @std_offset, @dst_offset, year)
|
38
|
+
end_dst = apply_rule(@dst_end_rule, @dst_offset, @std_offset, year)
|
39
|
+
|
40
|
+
end_dst.at < start_dst.at ? [end_dst, start_dst] : [start_dst, end_dst]
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Applies a given rule between offsets on a year.
|
46
|
+
def apply_rule(rule, from_offset, to_offset, year)
|
47
|
+
at = rule.at(from_offset, year)
|
48
|
+
Transition.new(to_offset, from_offset, at)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/lib/tzinfo/data_source.rb
CHANGED
@@ -179,7 +179,7 @@ module TZInfo
|
|
179
179
|
begin
|
180
180
|
return ZoneinfoDataSource.new
|
181
181
|
rescue ZoneinfoDirectoryNotFound
|
182
|
-
raise DataSourceNotFound, "No source of timezone data could be found.\nPlease refer to
|
182
|
+
raise DataSourceNotFound, "No source of timezone data could be found.\nPlease refer to https://tzinfo.github.io/datasourcenotfound for help resolving this error."
|
183
183
|
end
|
184
184
|
end
|
185
185
|
|
@@ -0,0 +1,136 @@
|
|
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
|
@@ -137,10 +137,33 @@ 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.2. Add a refinement to either silence the warning, or supply the method
|
158
|
+
# if needed.
|
159
|
+
if !Object.new.respond_to?(:untaint) || RUBY_VERSION =~ /\A(\d+)\.(\d+)(?:\.|\z)/ && ($1 == '2' && $2.to_i >= 7 || $1.to_i >= 3)
|
160
|
+
module UntaintExt
|
161
|
+
refine Object do
|
162
|
+
def untaint
|
163
|
+
self
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
144
167
|
end
|
145
168
|
end
|
146
169
|
end
|
@@ -1,4 +1,8 @@
|
|
1
1
|
module TZInfo
|
2
|
+
# Use send as a workaround for erroneous 'wrong number of arguments' errors
|
3
|
+
# with JRuby 9.0.5.0 when calling methods with Java implementations. See #114.
|
4
|
+
send(:using, RubyCoreSupport::UntaintExt) if RubyCoreSupport.const_defined?(:UntaintExt)
|
5
|
+
|
2
6
|
# A DataSource that loads data from the set of Ruby modules included in the
|
3
7
|
# TZInfo::Data library (tzinfo-data gem).
|
4
8
|
#
|
@@ -6,15 +10,30 @@ module TZInfo
|
|
6
10
|
#
|
7
11
|
# TZInfo::DataSource.set(:ruby)
|
8
12
|
class RubyDataSource < DataSource
|
9
|
-
# Base path for require.
|
10
|
-
REQUIRE_PATH = File.join('tzinfo', 'data', 'definitions')
|
11
|
-
|
12
13
|
# Whether the timezone index has been loaded yet.
|
13
14
|
@@timezone_index_loaded = false
|
14
15
|
|
15
16
|
# Whether the country index has been loaded yet.
|
16
17
|
@@country_index_loaded = false
|
17
18
|
|
19
|
+
# Initializes a new RubyDataSource instance.
|
20
|
+
def initialize
|
21
|
+
tzinfo_data = File.join('tzinfo', 'data')
|
22
|
+
begin
|
23
|
+
require(tzinfo_data)
|
24
|
+
|
25
|
+
data_file = File.join('', 'tzinfo', 'data.rb')
|
26
|
+
path = $".reverse_each.detect {|p| p.end_with?(data_file) }
|
27
|
+
if path
|
28
|
+
@base_path = File.join(File.dirname(path), 'data').untaint
|
29
|
+
else
|
30
|
+
@base_path = tzinfo_data
|
31
|
+
end
|
32
|
+
rescue LoadError
|
33
|
+
@base_path = tzinfo_data
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
18
37
|
# Returns a TimezoneInfo instance for a given identifier.
|
19
38
|
# Raises InvalidTimezoneIdentifier if the timezone is not found or the
|
20
39
|
# identifier is invalid.
|
@@ -93,27 +112,17 @@ module TZInfo
|
|
93
112
|
end
|
94
113
|
|
95
114
|
# Requires an index by its name.
|
96
|
-
def
|
115
|
+
def require_index(name)
|
97
116
|
require_data(*['indexes', name])
|
98
117
|
end
|
99
118
|
|
100
119
|
# Requires a file from tzinfo/data.
|
101
120
|
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)
|
121
|
+
require(File.join(@base_path, *file))
|
108
122
|
end
|
109
123
|
|
110
124
|
# Loads in the index of timezones if it hasn't already been loaded.
|
111
125
|
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
126
|
unless @@timezone_index_loaded
|
118
127
|
require_index('timezones')
|
119
128
|
@@timezone_index_loaded = true
|
@@ -122,11 +131,6 @@ module TZInfo
|
|
122
131
|
|
123
132
|
# Loads in the index of countries if it hasn't already been loaded.
|
124
133
|
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
134
|
unless @@country_index_loaded
|
131
135
|
require_index('countries')
|
132
136
|
@@country_index_loaded = true
|
@@ -160,6 +160,17 @@ module TZInfo
|
|
160
160
|
end
|
161
161
|
end
|
162
162
|
alias :day :mday
|
163
|
+
|
164
|
+
# Returns the day of the week (0..6 for Sunday to Saturday).
|
165
|
+
def wday
|
166
|
+
if @time
|
167
|
+
@time.wday
|
168
|
+
elsif @datetime
|
169
|
+
@datetime.wday
|
170
|
+
else
|
171
|
+
to_time.wday
|
172
|
+
end
|
173
|
+
end
|
163
174
|
|
164
175
|
# Returns the hour of the day (0..23).
|
165
176
|
def hour
|
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
|
@@ -600,8 +604,8 @@ module TZInfo
|
|
600
604
|
# Passing the invalid format string through to Time#strftime or
|
601
605
|
# DateTime#strtime would normally result in it being returned in the
|
602
606
|
# result. However, with Ruby 1.8.7 on Windows (as tested with Ruby
|
603
|
-
# 1.8.7-p374 from
|
604
|
-
# causes Time#strftime to always return an empty string (e.g.
|
607
|
+
# 1.8.7-p374 from https://rubyinstaller.org/downloads/archives),
|
608
|
+
# this causes Time#strftime to always return an empty string (e.g.
|
605
609
|
# Time.now.strftime('a %::::z b') returns '').
|
606
610
|
#
|
607
611
|
# Escape the percent to force it to be evaluated as a literal.
|