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
data/lib/tzinfo/timezone.rb
CHANGED
|
@@ -1,252 +1,300 @@
|
|
|
1
|
-
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
2
4
|
require 'set'
|
|
3
|
-
require 'thread_safe'
|
|
4
5
|
|
|
5
6
|
module TZInfo
|
|
6
|
-
# AmbiguousTime is raised to
|
|
7
|
-
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
7
|
+
# {AmbiguousTime} is raised to indicate that a specified local time has more
|
|
8
|
+
# than one possible equivalent UTC time. Such ambiguities arise when the
|
|
9
|
+
# clocks are set back in a time zone, most commonly during the repeated hour
|
|
10
|
+
# when transitioning from daylight savings time to standard time.
|
|
10
11
|
#
|
|
11
|
-
# AmbiguousTime is raised by
|
|
12
|
-
#
|
|
12
|
+
# {AmbiguousTime} is raised by {Timezone#local_datetime},
|
|
13
|
+
# {Timezone#local_time}, {Timezone#local_timestamp}, {Timezone#local_to_utc}
|
|
14
|
+
# and {Timezone#period_for_local} when using an ambiguous time and not
|
|
15
|
+
# specifying how to resolve the ambiguity.
|
|
13
16
|
class AmbiguousTime < StandardError
|
|
14
17
|
end
|
|
15
|
-
|
|
16
|
-
# PeriodNotFound is raised to indicate that no TimezonePeriod matching a
|
|
17
|
-
# time could be found.
|
|
18
|
+
|
|
19
|
+
# {PeriodNotFound} is raised to indicate that no {TimezonePeriod} matching a
|
|
20
|
+
# given time could be found.
|
|
18
21
|
class PeriodNotFound < StandardError
|
|
19
22
|
end
|
|
20
|
-
|
|
21
|
-
#
|
|
23
|
+
|
|
24
|
+
# {InvalidTimezoneIdentifier} is raised by {Timezone.get} if the identifier
|
|
25
|
+
# given is not valid.
|
|
22
26
|
class InvalidTimezoneIdentifier < StandardError
|
|
23
27
|
end
|
|
24
|
-
|
|
25
|
-
#
|
|
26
|
-
# Timezone.
|
|
28
|
+
|
|
29
|
+
# {UnknownTimezone} is raised when calling methods on an instance of
|
|
30
|
+
# {Timezone} that was created directly. To obtain {Timezone} instances the
|
|
31
|
+
# {Timezone.get} method should be used instead.
|
|
27
32
|
class UnknownTimezone < StandardError
|
|
28
33
|
end
|
|
29
|
-
|
|
30
|
-
# Timezone
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
+
|
|
35
|
+
# The {Timezone} class represents a time zone. It provides a factory method,
|
|
36
|
+
# {get}, to retrieve {Timezone} instances by their identifier.
|
|
37
|
+
#
|
|
38
|
+
# The {Timezone#to_local} method can be used to convert `Time` and `DateTime`
|
|
39
|
+
# instances to the local time for the zone. For example:
|
|
40
|
+
#
|
|
41
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
|
42
|
+
# local_time = tz.to_local(Time.utc(2005,8,29,15,35,0))
|
|
43
|
+
# local_datetime = tz.to_local(DateTime.new(2005,8,29,15,35,0))
|
|
34
44
|
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
37
|
-
# puts tz.local_to_utc(Time.utc(2005,8,29,11,35,0)).to_s
|
|
38
|
-
# puts tz.utc_to_local(1125315300).to_s
|
|
45
|
+
# Local `Time` and `DateTime` instances returned by `Timezone` have the
|
|
46
|
+
# correct local offset.
|
|
39
47
|
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
48
|
+
# The {Timezone#local_to_utc} method can by used to convert local `Time` and
|
|
49
|
+
# `DateTime` instances to UTC. {Timezone#local_to_utc} ignores the UTC offset
|
|
50
|
+
# of the supplied value and treats if it is a local time for the zone. For
|
|
51
|
+
# example:
|
|
42
52
|
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
53
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
|
54
|
+
# utc_time = tz.local_to_utc(Time.new(2005,8,29,11,35,0))
|
|
55
|
+
# utc_datetime = tz.local_to_utc(DateTime.new(2005,8,29,11,35,0))
|
|
56
|
+
#
|
|
57
|
+
# Each time zone is treated as sequence of periods of time ({TimezonePeriod})
|
|
58
|
+
# that observe the same offset ({TimezoneOffset}). Transitions
|
|
59
|
+
# ({TimezoneTransition}) denote the end of one period and the start of the
|
|
60
|
+
# next. The {Timezone} class has methods that allow the periods, offsets and
|
|
61
|
+
# transitions of a time zone to be interrogated.
|
|
62
|
+
#
|
|
63
|
+
# All methods that take `Time` objects as parameters can be used with
|
|
64
|
+
# arbitrary `Time`-like objects that respond to both `to_i` and `subsec` and
|
|
65
|
+
# optionally `utc_offset`.
|
|
66
|
+
#
|
|
67
|
+
# The {Timezone} class is thread-safe. It is safe to use class and instance
|
|
68
|
+
# methods of {Timezone} in concurrently executing threads. Instances of
|
|
69
|
+
# {Timezone} can be shared across thread boundaries.
|
|
70
|
+
#
|
|
71
|
+
# The IANA Time Zone Database maintainers recommend that time zone identifiers
|
|
72
|
+
# are not made visible to end-users (see [Names of
|
|
73
|
+
# timezones](https://data.iana.org/time-zones/theory.html#naming)). The
|
|
74
|
+
# {Country} class can be used to obtain lists of time zones by country,
|
|
75
|
+
# including user-friendly descriptions and approximate locations.
|
|
76
|
+
#
|
|
77
|
+
# @abstract The {get} method returns an instance of either {DataTimezone} or
|
|
78
|
+
# {LinkedTimezone}. The {get_proxy} method and other methods returning
|
|
79
|
+
# collections of time zones return instances of {TimezoneProxy}.
|
|
46
80
|
class Timezone
|
|
47
81
|
include Comparable
|
|
48
|
-
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
# @!visibility private
|
|
53
|
-
@@loaded_zones = nil
|
|
54
|
-
|
|
55
|
-
# Default value of the dst parameter of the local_to_utc and
|
|
56
|
-
# period_for_local methods.
|
|
82
|
+
|
|
83
|
+
# The default value of the dst parameter of the {local_datetime},
|
|
84
|
+
# {local_time}, {local_timestamp}, {local_to_utc} and {period_for_local}
|
|
85
|
+
# methods.
|
|
57
86
|
#
|
|
58
87
|
# @!visibility private
|
|
59
88
|
@@default_dst = nil
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
# Gets the default value of the optional dst parameter of the
|
|
71
|
-
# local_to_utc and period_for_local methods. Can be set to nil, true or
|
|
72
|
-
# false.
|
|
73
|
-
def self.default_dst
|
|
74
|
-
@@default_dst
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# Returns a timezone by its identifier (e.g. "Europe/London",
|
|
78
|
-
# "America/Chicago" or "UTC").
|
|
79
|
-
#
|
|
80
|
-
# Raises InvalidTimezoneIdentifier if the timezone couldn't be found.
|
|
81
|
-
def self.get(identifier)
|
|
82
|
-
instance = @@loaded_zones[identifier]
|
|
83
|
-
|
|
84
|
-
unless instance
|
|
85
|
-
# Thread-safety: It is possible that multiple equivalent Timezone
|
|
86
|
-
# instances could be created here in concurrently executing threads.
|
|
87
|
-
# The consequences of this are that the data may be loaded more than
|
|
88
|
-
# once (depending on the data source) and memoized calculations could
|
|
89
|
-
# be discarded. The performance benefit of ensuring that only a single
|
|
90
|
-
# instance is created is unlikely to be worth the overhead of only
|
|
91
|
-
# allowing one Timezone to be loaded at a time.
|
|
92
|
-
info = data_source.load_timezone_info(identifier)
|
|
93
|
-
instance = info.create_timezone
|
|
94
|
-
@@loaded_zones[instance.identifier] = instance
|
|
89
|
+
|
|
90
|
+
class << self
|
|
91
|
+
# Sets the default value of the optional `dst` parameter of the
|
|
92
|
+
# {local_datetime}, {local_time}, {local_timestamp}, {local_to_utc} and
|
|
93
|
+
# {period_for_local} methods. Can be set to `nil`, `true` or `false`.
|
|
94
|
+
#
|
|
95
|
+
# @param value [Boolean] `nil`, `true` or `false`.
|
|
96
|
+
def default_dst=(value)
|
|
97
|
+
@@default_dst = value.nil? ? nil : !!value
|
|
95
98
|
end
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
99
|
+
|
|
100
|
+
# Returns the default value of the optional `dst` parameter of the
|
|
101
|
+
# {local_time}, {local_datetime} and {local_timestamp}, {local_to_utc}
|
|
102
|
+
# and {period_for_local} methods (`nil`, `true` or `false`).
|
|
103
|
+
#
|
|
104
|
+
# {default_dst} defaults to `nil` unless changed with {default_dst=}.
|
|
105
|
+
#
|
|
106
|
+
# @return [Boolean] the default value of the optional `dst` parameter of
|
|
107
|
+
# the {local_time}, {local_datetime} and {local_timestamp},
|
|
108
|
+
# {local_to_utc} and {period_for_local} methods (`nil`, `true` or
|
|
109
|
+
# `false`).
|
|
110
|
+
def default_dst
|
|
111
|
+
@@default_dst
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Returns a time zone by its IANA Time Zone Database identifier (e.g.
|
|
115
|
+
# `"Europe/London"` or `"America/Chicago"`). Call {all_identifiers} for a
|
|
116
|
+
# list of all the valid identifiers.
|
|
117
|
+
#
|
|
118
|
+
# The {get} method will return a subclass of {Timezone}, either a
|
|
119
|
+
# {DataTimezone} (for a time zone defined by rules that set out when
|
|
120
|
+
# transitions occur) or a {LinkedTimezone} (for a time zone that is just a
|
|
121
|
+
# link to or alias for a another time zone).
|
|
122
|
+
#
|
|
123
|
+
# @param identifier [String] an IANA Time Zone Database time zone
|
|
124
|
+
# identifier.
|
|
125
|
+
# @return [Timezone] the {Timezone} with the given `identifier`.
|
|
126
|
+
# @raise [InvalidTimezoneIdentifier] if the `identifier` is not valid.
|
|
127
|
+
def get(identifier)
|
|
128
|
+
data_source.get_timezone_info(identifier).create_timezone
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Returns a proxy for the time zone with the given identifier. This allows
|
|
132
|
+
# loading of the time zone data to be deferred until it is first needed.
|
|
133
|
+
#
|
|
134
|
+
# The identifier will not be validated. If an invalid identifier is
|
|
135
|
+
# specified, no exception will be raised until the proxy is used.
|
|
136
|
+
#
|
|
137
|
+
# @param identifier [String] an IANA Time Zone Database time zone
|
|
138
|
+
# identifier.
|
|
139
|
+
# @return [TimezoneProxy] a proxy for the time zone with the given
|
|
140
|
+
# `identifier`.
|
|
141
|
+
def get_proxy(identifier)
|
|
142
|
+
TimezoneProxy.new(identifier)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Returns an `Array` of all the available time zones.
|
|
146
|
+
#
|
|
147
|
+
# {TimezoneProxy} instances are returned to avoid the overhead of loading
|
|
148
|
+
# time zone data until it is first needed.
|
|
149
|
+
#
|
|
150
|
+
# @return [Array<Timezone>] all available time zones.
|
|
151
|
+
def all
|
|
152
|
+
get_proxies(all_identifiers)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# @return [Array<String>] an `Array` containing the identifiers of all the
|
|
156
|
+
# available time zones.
|
|
157
|
+
def all_identifiers
|
|
158
|
+
data_source.timezone_identifiers
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Returns an `Array` of all the available time zones that are
|
|
162
|
+
# defined by offsets and transitions.
|
|
163
|
+
#
|
|
164
|
+
# {TimezoneProxy} instances are returned to avoid the overhead of loading
|
|
165
|
+
# time zone data until it is first needed.
|
|
166
|
+
#
|
|
167
|
+
# @return [Array<Timezone>] an `Array` of all the available time zones
|
|
168
|
+
# that are defined by offsets and transitions.
|
|
169
|
+
def all_data_zones
|
|
170
|
+
get_proxies(all_data_zone_identifiers)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# @return [Array<String>] an `Array` of the identifiers of all available
|
|
174
|
+
# time zones that are defined by offsets and transitions.
|
|
175
|
+
def all_data_zone_identifiers
|
|
176
|
+
data_source.data_timezone_identifiers
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# Returns an `Array` of all the available time zones that are
|
|
180
|
+
# defined as links to / aliases for other time zones.
|
|
181
|
+
#
|
|
182
|
+
# {TimezoneProxy} instances are returned to avoid the overhead of loading
|
|
183
|
+
# time zone data until it is first needed.
|
|
184
|
+
#
|
|
185
|
+
# @return [Array<Timezone>] an `Array` of all the available time zones
|
|
186
|
+
# that are defined as links to / aliases for other time zones.
|
|
187
|
+
def all_linked_zones
|
|
188
|
+
get_proxies(all_linked_zone_identifiers)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# @return [Array<String>] an `Array` of the identifiers of all available
|
|
192
|
+
# time zones that are defined as links to / aliases for other time zones.
|
|
193
|
+
def all_linked_zone_identifiers
|
|
194
|
+
data_source.linked_timezone_identifiers
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Returns an `Array` of all the time zones that are observed by at least
|
|
198
|
+
# one {Country}. This is not the complete set of time zones as some are
|
|
199
|
+
# not country specific (e.g. `'Etc/GMT'`).
|
|
200
|
+
#
|
|
201
|
+
# {TimezoneProxy} instances are returned to avoid the overhead of loading
|
|
202
|
+
# time zone data until it is first needed.
|
|
203
|
+
#
|
|
204
|
+
# @return [Array<Timezone>] an `Array` of all the time zones that are
|
|
205
|
+
# observed by at least one {Country}.
|
|
206
|
+
def all_country_zones
|
|
207
|
+
Country.all.map(&:zones).flatten.uniq
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Returns an `Array` of the identifiers of all the time zones that are
|
|
211
|
+
# observed by at least one {Country}. This is not the complete set of time
|
|
212
|
+
# zone identifiers as some are not country specific (e.g. `'Etc/GMT'`).
|
|
213
|
+
#
|
|
214
|
+
# {TimezoneProxy} instances are returned to avoid the overhead of loading
|
|
215
|
+
# time zone data until it is first needed.
|
|
216
|
+
#
|
|
217
|
+
# @return [Array<String>] an `Array` of the identifiers of all the time
|
|
218
|
+
# zones that are observed by at least one {Country}.
|
|
219
|
+
def all_country_zone_identifiers
|
|
220
|
+
Country.all.map(&:zone_identifiers).flatten.uniq
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
private
|
|
224
|
+
|
|
225
|
+
# @param [Enumerable<String>] identifiers an `Enumerable` of time zone
|
|
226
|
+
# identifiers.
|
|
227
|
+
# @return [Array<TimezoneProxy>] an `Array` of {TimezoneProxy}
|
|
228
|
+
# instances corresponding to the given identifiers.
|
|
229
|
+
def get_proxies(identifiers)
|
|
230
|
+
identifiers.collect {|identifier| get_proxy(identifier)}
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# @return [DataSource] the current DataSource.
|
|
234
|
+
def data_source
|
|
235
|
+
DataSource.get
|
|
116
236
|
end
|
|
117
237
|
end
|
|
118
|
-
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
# Returns TimezoneProxy objects to avoid the overhead of loading Timezone
|
|
122
|
-
# definitions until a conversion is actually required.
|
|
123
|
-
def self.all
|
|
124
|
-
get_proxies(all_identifiers)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
# Returns an array containing the identifiers of all the available
|
|
128
|
-
# Timezones.
|
|
129
|
-
def self.all_identifiers
|
|
130
|
-
data_source.timezone_identifiers
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# Returns an array containing all the available Timezones that are based
|
|
134
|
-
# on data (are not links to other Timezones).
|
|
135
|
-
#
|
|
136
|
-
# Returns TimezoneProxy objects to avoid the overhead of loading Timezone
|
|
137
|
-
# definitions until a conversion is actually required.
|
|
138
|
-
def self.all_data_zones
|
|
139
|
-
get_proxies(all_data_zone_identifiers)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Returns an array containing the identifiers of all the available
|
|
143
|
-
# Timezones that are based on data (are not links to other Timezones)..
|
|
144
|
-
def self.all_data_zone_identifiers
|
|
145
|
-
data_source.data_timezone_identifiers
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
# Returns an array containing all the available Timezones that are links
|
|
149
|
-
# to other Timezones.
|
|
150
|
-
#
|
|
151
|
-
# Returns TimezoneProxy objects to avoid the overhead of loading Timezone
|
|
152
|
-
# definitions until a conversion is actually required.
|
|
153
|
-
def self.all_linked_zones
|
|
154
|
-
get_proxies(all_linked_zone_identifiers)
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# Returns an array containing the identifiers of all the available
|
|
158
|
-
# Timezones that are links to other Timezones.
|
|
159
|
-
def self.all_linked_zone_identifiers
|
|
160
|
-
data_source.linked_timezone_identifiers
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
# Returns all the Timezones defined for all Countries. This is not the
|
|
164
|
-
# complete set of Timezones as some are not country specific (e.g.
|
|
165
|
-
# 'Etc/GMT').
|
|
166
|
-
#
|
|
167
|
-
# Returns TimezoneProxy objects to avoid the overhead of loading Timezone
|
|
168
|
-
# definitions until a conversion is actually required.
|
|
169
|
-
def self.all_country_zones
|
|
170
|
-
Country.all_codes.inject([]) do |zones,country|
|
|
171
|
-
zones += Country.get(country).zones
|
|
172
|
-
end.uniq
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
# Returns all the zone identifiers defined for all Countries. This is not the
|
|
176
|
-
# complete set of zone identifiers as some are not country specific (e.g.
|
|
177
|
-
# 'Etc/GMT'). You can obtain a Timezone instance for a given identifier
|
|
178
|
-
# with the get method.
|
|
179
|
-
def self.all_country_zone_identifiers
|
|
180
|
-
Country.all_codes.inject([]) do |zones,country|
|
|
181
|
-
zones += Country.get(country).zone_identifiers
|
|
182
|
-
end.uniq
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
# Returns all US Timezone instances. A shortcut for
|
|
186
|
-
# TZInfo::Country.get('US').zones.
|
|
187
|
-
#
|
|
188
|
-
# Returns TimezoneProxy objects to avoid the overhead of loading Timezone
|
|
189
|
-
# definitions until a conversion is actually required.
|
|
190
|
-
def self.us_zones
|
|
191
|
-
Country.get('US').zones
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
# Returns all US zone identifiers. A shortcut for
|
|
195
|
-
# TZInfo::Country.get('US').zone_identifiers.
|
|
196
|
-
def self.us_zone_identifiers
|
|
197
|
-
Country.get('US').zone_identifiers
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
# The identifier of the timezone, e.g. "Europe/Paris".
|
|
238
|
+
|
|
239
|
+
# @return [String] the identifier of the time zone, for example,
|
|
240
|
+
# `"Europe/Paris"`.
|
|
201
241
|
def identifier
|
|
202
242
|
raise_unknown_timezone
|
|
203
243
|
end
|
|
204
|
-
|
|
205
|
-
#
|
|
244
|
+
|
|
245
|
+
# @return [String] the identifier of the time zone, for example,
|
|
246
|
+
# `"Europe/Paris"`.
|
|
206
247
|
def name
|
|
207
248
|
# Don't use alias, as identifier gets overridden.
|
|
208
249
|
identifier
|
|
209
250
|
end
|
|
210
|
-
|
|
211
|
-
#
|
|
251
|
+
|
|
252
|
+
# @return [String] {identifier}, modified to make it more readable.
|
|
212
253
|
def to_s
|
|
213
254
|
friendly_identifier
|
|
214
255
|
end
|
|
215
|
-
|
|
216
|
-
#
|
|
256
|
+
|
|
257
|
+
# @return [String] the internal object state as a programmer-readable
|
|
258
|
+
# `String`.
|
|
217
259
|
def inspect
|
|
218
260
|
"#<#{self.class}: #{identifier}>"
|
|
219
261
|
end
|
|
220
|
-
|
|
221
|
-
# Returns
|
|
222
|
-
# omit the first part of the identifier (typically a
|
|
223
|
-
# there is more than one part.
|
|
262
|
+
|
|
263
|
+
# Returns {identifier}, modified to make it more readable. Set
|
|
264
|
+
# `skip_first_part` to omit the first part of the identifier (typically a
|
|
265
|
+
# region name) where there is more than one part.
|
|
224
266
|
#
|
|
225
267
|
# For example:
|
|
226
268
|
#
|
|
227
|
-
#
|
|
228
|
-
#
|
|
229
|
-
#
|
|
230
|
-
#
|
|
269
|
+
# TZInfo::Timezone.get('Europe/Paris').friendly_identifier(false) #=> "Europe - Paris"
|
|
270
|
+
# TZInfo::Timezone.get('Europe/Paris').friendly_identifier(true) #=> "Paris"
|
|
271
|
+
# TZInfo::Timezone.get('America/Indiana/Knox').friendly_identifier(false) #=> "America - Knox, Indiana"
|
|
272
|
+
# TZInfo::Timezone.get('America/Indiana/Knox').friendly_identifier(true) #=> "Knox, Indiana"
|
|
273
|
+
#
|
|
274
|
+
# @param skip_first_part [Boolean] whether the first part of the identifier
|
|
275
|
+
# (typically a region name) should be omitted.
|
|
276
|
+
# @return [String] the modified identifier.
|
|
231
277
|
def friendly_identifier(skip_first_part = false)
|
|
232
|
-
|
|
278
|
+
id = identifier
|
|
279
|
+
id = id.encode(Encoding::UTF_8) unless id.encoding.ascii_compatible?
|
|
280
|
+
parts = id.split('/')
|
|
233
281
|
if parts.empty?
|
|
234
282
|
# shouldn't happen
|
|
235
283
|
identifier
|
|
236
|
-
elsif parts.length == 1
|
|
284
|
+
elsif parts.length == 1
|
|
237
285
|
parts[0]
|
|
238
286
|
else
|
|
239
287
|
prefix = skip_first_part ? nil : "#{parts[0]} - "
|
|
240
288
|
|
|
241
289
|
parts = parts.drop(1).map do |part|
|
|
242
290
|
part.gsub!(/_/, ' ')
|
|
243
|
-
|
|
291
|
+
|
|
244
292
|
if part.index(/[a-z]/)
|
|
245
293
|
# Missing a space if a lower case followed by an upper case and the
|
|
246
294
|
# name isn't McXxxx.
|
|
247
295
|
part.gsub!(/([^M][a-z])([A-Z])/, '\1 \2')
|
|
248
296
|
part.gsub!(/([M][a-bd-z])([A-Z])/, '\1 \2')
|
|
249
|
-
|
|
297
|
+
|
|
250
298
|
# Missing an apostrophe if two consecutive upper case characters.
|
|
251
299
|
part.gsub!(/([A-Z])([A-Z])/, '\1\'\2')
|
|
252
300
|
end
|
|
@@ -257,417 +305,846 @@ module TZInfo
|
|
|
257
305
|
"#{prefix}#{parts.reverse.join(', ')}"
|
|
258
306
|
end
|
|
259
307
|
end
|
|
260
|
-
|
|
261
|
-
# Returns the TimezonePeriod
|
|
262
|
-
#
|
|
263
|
-
#
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
#
|
|
269
|
-
#
|
|
270
|
-
#
|
|
271
|
-
|
|
272
|
-
def periods_for_local(local)
|
|
308
|
+
|
|
309
|
+
# Returns the {TimezonePeriod} that is valid at a given time.
|
|
310
|
+
#
|
|
311
|
+
# Unlike {period_for_local} and {period_for_utc}, the UTC offset of the
|
|
312
|
+
# `time` parameter is taken into consideration.
|
|
313
|
+
#
|
|
314
|
+
# @param time [Object] a `Time`, `DateTime` or {Timestamp}.
|
|
315
|
+
# @return [TimezonePeriod] the {TimezonePeriod} that is valid at `time`.
|
|
316
|
+
# @raise [ArgumentError] if `time` is `nil`.
|
|
317
|
+
# @raise [ArgumentError] if `time` is a {Timestamp} with an unspecified
|
|
318
|
+
# offset.
|
|
319
|
+
def period_for(time)
|
|
273
320
|
raise_unknown_timezone
|
|
274
321
|
end
|
|
275
|
-
|
|
276
|
-
# Returns
|
|
277
|
-
#
|
|
322
|
+
|
|
323
|
+
# Returns the set of {TimezonePeriod}s that are valid for the given
|
|
324
|
+
# local time as an `Array`.
|
|
278
325
|
#
|
|
279
|
-
#
|
|
280
|
-
#
|
|
326
|
+
# The UTC offset of the `local_time` parameter is ignored (it is treated as
|
|
327
|
+
# a time in the time zone represented by `self`).
|
|
281
328
|
#
|
|
282
|
-
#
|
|
283
|
-
#
|
|
284
|
-
#
|
|
329
|
+
# This will typically return an `Array` containing a single
|
|
330
|
+
# {TimezonePeriod}. More than one {TimezonePeriod} will be returned when the
|
|
331
|
+
# local time is ambiguous (for example, when daylight savings time ends). An
|
|
332
|
+
# empty `Array` will be returned when the local time is not valid (for
|
|
333
|
+
# example, when daylight savings time begins).
|
|
285
334
|
#
|
|
286
|
-
#
|
|
287
|
-
#
|
|
288
|
-
# If a transition falls on utc_from, it will be included.
|
|
335
|
+
# To obtain just a single {TimezonePeriod} in all cases, use
|
|
336
|
+
# {period_for_local} instead and specify how ambiguities should be resolved.
|
|
289
337
|
#
|
|
290
|
-
#
|
|
291
|
-
#
|
|
338
|
+
# @param local_time [Object] a `Time`, `DateTime` or {Timestamp}.
|
|
339
|
+
# @return [Array<TimezonePeriod>] the set of {TimezonePeriod}s that are
|
|
340
|
+
# valid at `local_time`.
|
|
341
|
+
# @raise [ArgumentError] if `local_time` is `nil`.
|
|
342
|
+
def periods_for_local(local_time)
|
|
343
|
+
raise_unknown_timezone
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
# Returns an `Array` of {TimezoneTransition} instances representing the
|
|
347
|
+
# times where the UTC offset of the timezone changes.
|
|
292
348
|
#
|
|
293
|
-
#
|
|
294
|
-
# integer timestamps (Time.to_i).
|
|
349
|
+
# Transitions are returned up to a given time (`to`).
|
|
295
350
|
#
|
|
296
|
-
#
|
|
297
|
-
#
|
|
298
|
-
|
|
351
|
+
# A from time may also be supplied using the `from` parameter. If from is
|
|
352
|
+
# not `nil`, only transitions from that time onwards will be returned.
|
|
353
|
+
#
|
|
354
|
+
# Comparisons with `to` are exclusive. Comparisons with `from` are
|
|
355
|
+
# inclusive. If a transition falls precisely on `to`, it will be excluded.
|
|
356
|
+
# If a transition falls on `from`, it will be included.
|
|
357
|
+
#
|
|
358
|
+
# @param to [Object] a `Time`, `DateTime` or {Timestamp} specifying the
|
|
359
|
+
# latest (exclusive) transition to return.
|
|
360
|
+
# @param from [Object] an optional `Time`, `DateTime` or {Timestamp}
|
|
361
|
+
# specifying the earliest (inclusive) transition to return.
|
|
362
|
+
# @return [Array<TimezoneTransition>] the transitions that are earlier than
|
|
363
|
+
# `to` and, if specified, at or later than `from`. Transitions are ordered
|
|
364
|
+
# by when they occur, from earliest to latest.
|
|
365
|
+
# @raise [ArgumentError] if `from` is specified and `to` is not greater than
|
|
366
|
+
# `from`.
|
|
367
|
+
# @raise [ArgumentError] is raised if `to` is `nil`.
|
|
368
|
+
# @raise [ArgumentError] if either `to` or `from` is a {Timestamp} with an
|
|
369
|
+
# unspecified offset.
|
|
370
|
+
def transitions_up_to(to, from = nil)
|
|
299
371
|
raise_unknown_timezone
|
|
300
372
|
end
|
|
301
|
-
|
|
302
|
-
# Returns the canonical Timezone instance for this Timezone.
|
|
373
|
+
|
|
374
|
+
# Returns the canonical {Timezone} instance for this {Timezone}.
|
|
303
375
|
#
|
|
304
|
-
# The IANA Time Zone database contains two types of definition: Zones and
|
|
305
|
-
# Links. Zones are defined by rules that set out when transitions occur.
|
|
306
|
-
# Links are just references to fully defined Zone, creating an alias for
|
|
376
|
+
# The IANA Time Zone database contains two types of definition: Zones and
|
|
377
|
+
# Links. Zones are defined by rules that set out when transitions occur.
|
|
378
|
+
# Links are just references to fully defined Zone, creating an alias for
|
|
307
379
|
# that Zone.
|
|
308
380
|
#
|
|
309
|
-
# Links are commonly used where a time zone has been renamed in a
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
381
|
+
# Links are commonly used where a time zone has been renamed in a release of
|
|
382
|
+
# the Time Zone database. For example, the US/Eastern Zone was renamed as
|
|
383
|
+
# America/New_York. A US/Eastern Link was added in its place, linking to
|
|
384
|
+
# (and creating an alias for) America/New_York.
|
|
313
385
|
#
|
|
314
|
-
# Links are also used for time zones that are currently identical to a full
|
|
315
|
-
# Zone, but that are administered
|
|
386
|
+
# Links are also used for time zones that are currently identical to a full
|
|
387
|
+
# Zone, but that are administered separately. For example, Europe/Vatican is
|
|
316
388
|
# a Link to (and alias for) Europe/Rome.
|
|
317
389
|
#
|
|
318
|
-
# For a full Zone, canonical_zone returns
|
|
390
|
+
# For a full Zone (implemented by {DataTimezone}), {canonical_zone} returns
|
|
391
|
+
# self.
|
|
319
392
|
#
|
|
320
|
-
# For a Link, canonical_zone returns a
|
|
321
|
-
# full Zone that the link targets.
|
|
393
|
+
# For a Link (implemented by {LinkedTimezone}), {canonical_zone} returns a
|
|
394
|
+
# {Timezone} instance representing the full Zone that the link targets.
|
|
322
395
|
#
|
|
323
396
|
# TZInfo can be used with different data sources (see the documentation for
|
|
324
|
-
# TZInfo::DataSource).
|
|
325
|
-
#
|
|
326
|
-
#
|
|
327
|
-
#
|
|
328
|
-
#
|
|
329
|
-
#
|
|
330
|
-
#
|
|
331
|
-
#
|
|
332
|
-
#
|
|
333
|
-
#
|
|
334
|
-
#
|
|
335
|
-
# The TZInfo::DataSource.get method can be used to check which DataSource
|
|
397
|
+
# {TZInfo::DataSource}). Some DataSource implementations may not support
|
|
398
|
+
# distinguishing between full Zones and Links and will treat all time zones
|
|
399
|
+
# as full Zones. In this case, {canonical_zone} will always return `self`.
|
|
400
|
+
#
|
|
401
|
+
# There are two built-in DataSource implementations.
|
|
402
|
+
# {DataSources::RubyDataSource} (which will be used if the tzinfo-data gem
|
|
403
|
+
# is available) supports Link zones. {DataSources::ZoneinfoDataSource}
|
|
404
|
+
# returns Link zones as if they were full Zones. If the {canonical_zone} or
|
|
405
|
+
# {canonical_identifier} methods are needed, the tzinfo-data gem should be
|
|
406
|
+
# installed.
|
|
407
|
+
#
|
|
408
|
+
# The {TZInfo::DataSource.get} method can be used to check which DataSource
|
|
336
409
|
# implementation is being used.
|
|
410
|
+
#
|
|
411
|
+
# @return [Timezone] the canonical {Timezone} instance for this {Timezone}.
|
|
337
412
|
def canonical_zone
|
|
338
413
|
raise_unknown_timezone
|
|
339
414
|
end
|
|
340
|
-
|
|
341
|
-
# Returns the TimezonePeriod
|
|
342
|
-
# a DateTime, Time or integer timestamp (Time.to_i). Any timezone
|
|
343
|
-
# information in local is ignored (it is treated as a time in the current
|
|
344
|
-
# timezone).
|
|
415
|
+
|
|
416
|
+
# Returns the {TimezonePeriod} that is valid at a given time.
|
|
345
417
|
#
|
|
346
|
-
#
|
|
347
|
-
#
|
|
348
|
-
#
|
|
349
|
-
#
|
|
418
|
+
# The UTC offset of the `utc_time` parameter is ignored (it is treated as a
|
|
419
|
+
# UTC time). Use the {period_for} method instead if the UTC offset of the
|
|
420
|
+
# time needs to be taken into consideration.
|
|
421
|
+
#
|
|
422
|
+
# @param utc_time [Object] a `Time`, `DateTime` or {Timestamp}.
|
|
423
|
+
# @return [TimezonePeriod] the {TimezonePeriod} that is valid at `utc_time`.
|
|
424
|
+
# @raise [ArgumentError] if `utc_time` is `nil`.
|
|
425
|
+
def period_for_utc(utc_time)
|
|
426
|
+
raise ArgumentError, 'utc_time must be specified' unless utc_time
|
|
427
|
+
period_for(Timestamp.for(utc_time, :treat_as_utc))
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
# Returns the {TimezonePeriod} that is valid at the given local time.
|
|
350
431
|
#
|
|
351
|
-
#
|
|
432
|
+
# The UTC offset of the `local_time` parameter is ignored (it is treated as
|
|
433
|
+
# a time in the time zone represented by `self`). Use the {period_for}
|
|
434
|
+
# method instead if the the UTC offset of the time needs to be taken into
|
|
435
|
+
# consideration.
|
|
436
|
+
#
|
|
437
|
+
# _Warning:_ There are local times that have no equivalent UTC times (for
|
|
438
|
+
# example, during the transition from standard time to daylight savings
|
|
439
|
+
# time). There are also local times that have more than one UTC equivalent
|
|
440
|
+
# (for example, during the transition from daylight savings time to standard
|
|
441
|
+
# time).
|
|
442
|
+
#
|
|
443
|
+
# In the first case (no equivalent UTC time), a {PeriodNotFound} exception
|
|
352
444
|
# will be raised.
|
|
353
445
|
#
|
|
354
|
-
# In the second case (more than one equivalent UTC time), an AmbiguousTime
|
|
355
|
-
# exception will be raised unless the optional dst parameter or block
|
|
356
|
-
# handles the ambiguity.
|
|
446
|
+
# In the second case (more than one equivalent UTC time), an {AmbiguousTime}
|
|
447
|
+
# exception will be raised unless the optional `dst` parameter or block
|
|
448
|
+
# handles the ambiguity.
|
|
357
449
|
#
|
|
358
450
|
# If the ambiguity is due to a transition from daylight savings time to
|
|
359
|
-
# standard time, the dst parameter can be used to select whether the
|
|
360
|
-
# daylight savings time or local time is used. For example,
|
|
361
|
-
#
|
|
362
|
-
#
|
|
363
|
-
#
|
|
364
|
-
#
|
|
365
|
-
#
|
|
366
|
-
# Specifying dst=true would the daylight savings period from
|
|
367
|
-
# October 2004. Specifying dst=false would return the
|
|
368
|
-
# from October 2004 to April 2005.
|
|
369
|
-
#
|
|
370
|
-
#
|
|
371
|
-
#
|
|
372
|
-
#
|
|
373
|
-
#
|
|
374
|
-
#
|
|
375
|
-
#
|
|
376
|
-
#
|
|
377
|
-
#
|
|
378
|
-
#
|
|
379
|
-
#
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
451
|
+
# standard time, the `dst` parameter can be used to select whether the
|
|
452
|
+
# daylight savings time or local time is used. For example, the following
|
|
453
|
+
# code would raise an {AmbiguousTime} exception:
|
|
454
|
+
#
|
|
455
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
|
456
|
+
# tz.period_for_local(Time.new(2004,10,31,1,30,0))
|
|
457
|
+
#
|
|
458
|
+
# Specifying `dst = true` would select the daylight savings period from
|
|
459
|
+
# April to October 2004. Specifying `dst = false` would return the
|
|
460
|
+
# standard time period from October 2004 to April 2005.
|
|
461
|
+
#
|
|
462
|
+
# The `dst` parameter will not be able to resolve an ambiguity resulting
|
|
463
|
+
# from the clocks being set back without changing from daylight savings time
|
|
464
|
+
# to standard time. In this case, if a block is specified, it will be called
|
|
465
|
+
# to resolve the ambiguity. The block must take a single parameter - an
|
|
466
|
+
# `Array` of {TimezonePeriod}s that need to be resolved. The block can
|
|
467
|
+
# select and return a single {TimezonePeriod} or return `nil` or an empty
|
|
468
|
+
# `Array` to cause an {AmbiguousTime} exception to be raised.
|
|
469
|
+
#
|
|
470
|
+
# The default value of the `dst` parameter can be specified using
|
|
471
|
+
# {Timezone.default_dst=}.
|
|
472
|
+
#
|
|
473
|
+
# @param local_time [Object] a `Time`, `DateTime` or {Timestamp}.
|
|
474
|
+
# @param dst [Boolean] whether to resolve ambiguous local times by always
|
|
475
|
+
# selecting the period observing daylight savings time (`true`), always
|
|
476
|
+
# selecting the period observing standard time (`false`), or leaving the
|
|
477
|
+
# ambiguity unresolved (`nil`).
|
|
478
|
+
# @yield [periods] if the `dst` parameter did not resolve an ambiguity, an
|
|
479
|
+
# optional block is yielded to.
|
|
480
|
+
# @yieldparam periods [Array<TimezonePeriod>] an `Array` containing all
|
|
481
|
+
# the {TimezonePeriod}s that still match `local_time` after applying the
|
|
482
|
+
# `dst` parameter.
|
|
483
|
+
# @yieldreturn [Object] to resolve the ambiguity: a chosen {TimezonePeriod}
|
|
484
|
+
# or an `Array` containing a chosen {TimezonePeriod}; to leave the
|
|
485
|
+
# ambiguity unresolved: an empty `Array`, an `Array` containing more than
|
|
486
|
+
# one {TimezonePeriod}, or `nil`.
|
|
487
|
+
# @return [TimezonePeriod] the {TimezonePeriod} that is valid at
|
|
488
|
+
# `local_time`.
|
|
489
|
+
# @raise [ArgumentError] if `local_time` is `nil`.
|
|
490
|
+
# @raise [PeriodNotFound] if `local_time` is not valid for the time zone
|
|
491
|
+
# (there is no equivalent UTC time).
|
|
492
|
+
# @raise [AmbiguousTime] if `local_time` was ambiguous for the time zone and
|
|
493
|
+
# the `dst` parameter or block did not resolve the ambiguity.
|
|
494
|
+
def period_for_local(local_time, dst = Timezone.default_dst)
|
|
495
|
+
raise ArgumentError, 'local_time must be specified' unless local_time
|
|
496
|
+
local_time = Timestamp.for(local_time, :ignore)
|
|
497
|
+
results = periods_for_local(local_time)
|
|
498
|
+
|
|
383
499
|
if results.empty?
|
|
384
|
-
raise PeriodNotFound
|
|
500
|
+
raise PeriodNotFound, "#{local_time.strftime('%Y-%m-%d %H:%M:%S')} is an invalid local time."
|
|
385
501
|
elsif results.size < 2
|
|
386
502
|
results.first
|
|
387
503
|
else
|
|
388
504
|
# ambiguous result try to resolve
|
|
389
|
-
|
|
505
|
+
|
|
390
506
|
if !dst.nil?
|
|
391
507
|
matches = results.find_all {|period| period.dst? == dst}
|
|
392
|
-
results = matches if !matches.empty?
|
|
508
|
+
results = matches if !matches.empty?
|
|
393
509
|
end
|
|
394
|
-
|
|
510
|
+
|
|
395
511
|
if results.size < 2
|
|
396
512
|
results.first
|
|
397
513
|
else
|
|
398
514
|
# still ambiguous, try the block
|
|
399
|
-
|
|
515
|
+
|
|
400
516
|
if block_given?
|
|
401
517
|
results = yield results
|
|
402
518
|
end
|
|
403
|
-
|
|
519
|
+
|
|
404
520
|
if results.is_a?(TimezonePeriod)
|
|
405
521
|
results
|
|
406
522
|
elsif results && results.size == 1
|
|
407
523
|
results.first
|
|
408
|
-
else
|
|
409
|
-
raise AmbiguousTime, "#{
|
|
524
|
+
else
|
|
525
|
+
raise AmbiguousTime, "#{local_time.strftime('%Y-%m-%d %H:%M:%S')} is an ambiguous local time."
|
|
410
526
|
end
|
|
411
527
|
end
|
|
412
|
-
end
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
# Converts a time
|
|
416
|
-
#
|
|
417
|
-
#
|
|
418
|
-
# a
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
#
|
|
426
|
-
#
|
|
427
|
-
#
|
|
428
|
-
#
|
|
429
|
-
#
|
|
430
|
-
#
|
|
431
|
-
#
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# Converts a time to the local time for the time zone.
|
|
532
|
+
#
|
|
533
|
+
# The result will be of type {TimeWithOffset} (if passed a `Time`),
|
|
534
|
+
# {DateTimeWithOffset} (if passed a `DateTime`) or {TimestampWithOffset} (if
|
|
535
|
+
# passed a {Timestamp}). {TimeWithOffset}, {DateTimeWithOffset} and
|
|
536
|
+
# {TimestampWithOffset} are subclasses of `Time`, `DateTime` and {Timestamp}
|
|
537
|
+
# that provide additional information about the local result.
|
|
538
|
+
#
|
|
539
|
+
# Unlike {utc_to_local}, {to_local} takes the UTC offset of the given time
|
|
540
|
+
# into consideration.
|
|
541
|
+
#
|
|
542
|
+
# @param time [Object] a `Time`, `DateTime` or {Timestamp}.
|
|
543
|
+
# @return [Object] the local equivalent of `time` as a {TimeWithOffset},
|
|
544
|
+
# {DateTimeWithOffset} or {TimestampWithOffset}.
|
|
545
|
+
# @raise [ArgumentError] if `time` is `nil`.
|
|
546
|
+
# @raise [ArgumentError] if `time` is a {Timestamp} that does not have a
|
|
547
|
+
# specified UTC offset.
|
|
548
|
+
def to_local(time)
|
|
549
|
+
raise ArgumentError, 'time must be specified' unless time
|
|
550
|
+
|
|
551
|
+
Timestamp.for(time) do |ts|
|
|
552
|
+
TimestampWithOffset.set_timezone_offset(ts, period_for(ts).offset)
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
# Converts a time in UTC to the local time for the time zone.
|
|
557
|
+
#
|
|
558
|
+
# The result will be of type {TimeWithOffset} (if passed a `Time`),
|
|
559
|
+
# {DateTimeWithOffset} (if passed a `DateTime`) or {TimestampWithOffset} (if
|
|
560
|
+
# passed a {Timestamp}). {TimeWithOffset}, {DateTimeWithOffset} and
|
|
561
|
+
# {TimestampWithOffset} are subclasses of `Time`, `DateTime` and {Timestamp}
|
|
562
|
+
# that provide additional information about the local result.
|
|
563
|
+
#
|
|
564
|
+
# The UTC offset of the `utc_time` parameter is ignored (it is treated as a
|
|
565
|
+
# UTC time). Use the {to_local} method instead if the the UTC offset of the
|
|
566
|
+
# time needs to be taken into consideration.
|
|
567
|
+
#
|
|
568
|
+
# @param utc_time [Object] a `Time`, `DateTime` or {Timestamp}.
|
|
569
|
+
# @return [Object] the local equivalent of `utc_time` as a {TimeWithOffset},
|
|
570
|
+
# {DateTimeWithOffset} or {TimestampWithOffset}.
|
|
571
|
+
# @raise [ArgumentError] if `utc_time` is `nil`.
|
|
572
|
+
def utc_to_local(utc_time)
|
|
573
|
+
raise ArgumentError, 'utc_time must be specified' unless utc_time
|
|
574
|
+
|
|
575
|
+
Timestamp.for(utc_time, :treat_as_utc) do |ts|
|
|
576
|
+
to_local(ts)
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
# Converts a local time for the time zone to UTC.
|
|
581
|
+
#
|
|
582
|
+
# The result will either be a `Time`, `DateTime` or {Timestamp} according to
|
|
583
|
+
# the type of the `local_time` parameter.
|
|
584
|
+
#
|
|
585
|
+
# The UTC offset of the `local_time` parameter is ignored (it is treated as
|
|
586
|
+
# a time in the time zone represented by `self`).
|
|
587
|
+
#
|
|
588
|
+
# _Warning:_ There are local times that have no equivalent UTC times (for
|
|
589
|
+
# example, during the transition from standard time to daylight savings
|
|
590
|
+
# time). There are also local times that have more than one UTC equivalent
|
|
591
|
+
# (for example, during the transition from daylight savings time to standard
|
|
592
|
+
# time).
|
|
593
|
+
#
|
|
594
|
+
# In the first case (no equivalent UTC time), a {PeriodNotFound} exception
|
|
436
595
|
# will be raised.
|
|
437
596
|
#
|
|
438
|
-
# In the second case (more than one equivalent UTC time), an AmbiguousTime
|
|
439
|
-
# exception will be raised unless the optional dst parameter or block
|
|
440
|
-
# handles the ambiguity.
|
|
597
|
+
# In the second case (more than one equivalent UTC time), an {AmbiguousTime}
|
|
598
|
+
# exception will be raised unless the optional `dst` parameter or block
|
|
599
|
+
# handles the ambiguity.
|
|
441
600
|
#
|
|
442
601
|
# If the ambiguity is due to a transition from daylight savings time to
|
|
443
|
-
# standard time, the dst parameter can be used to select whether the
|
|
444
|
-
# daylight savings time or local time is used. For example,
|
|
445
|
-
#
|
|
446
|
-
#
|
|
447
|
-
#
|
|
448
|
-
#
|
|
449
|
-
#
|
|
450
|
-
# Specifying dst=true would
|
|
451
|
-
# would return
|
|
452
|
-
#
|
|
453
|
-
#
|
|
454
|
-
#
|
|
455
|
-
#
|
|
456
|
-
#
|
|
457
|
-
# to
|
|
458
|
-
#
|
|
459
|
-
#
|
|
460
|
-
#
|
|
461
|
-
#
|
|
462
|
-
#
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
602
|
+
# standard time, the `dst` parameter can be used to select whether the
|
|
603
|
+
# daylight savings time or local time is used. For example, the following
|
|
604
|
+
# code would raise an {AmbiguousTime} exception:
|
|
605
|
+
#
|
|
606
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
|
607
|
+
# tz.period_for_local(Time.new(2004,10,31,1,30,0))
|
|
608
|
+
#
|
|
609
|
+
# Specifying `dst = true` would select the daylight savings period from
|
|
610
|
+
# April to October 2004. Specifying `dst = false` would return the
|
|
611
|
+
# standard time period from October 2004 to April 2005.
|
|
612
|
+
#
|
|
613
|
+
# The `dst` parameter will not be able to resolve an ambiguity resulting
|
|
614
|
+
# from the clocks being set back without changing from daylight savings time
|
|
615
|
+
# to standard time. In this case, if a block is specified, it will be called
|
|
616
|
+
# to resolve the ambiguity. The block must take a single parameter - an
|
|
617
|
+
# `Array` of {TimezonePeriod}s that need to be resolved. The block can
|
|
618
|
+
# select and return a single {TimezonePeriod} or return `nil` or an empty
|
|
619
|
+
# `Array` to cause an {AmbiguousTime} exception to be raised.
|
|
620
|
+
#
|
|
621
|
+
# The default value of the `dst` parameter can be specified using
|
|
622
|
+
# {Timezone.default_dst=}.
|
|
623
|
+
#
|
|
624
|
+
# @param local_time [Object] a `Time`, `DateTime` or {Timestamp}.
|
|
625
|
+
# @param dst [Boolean] whether to resolve ambiguous local times by always
|
|
626
|
+
# selecting the period observing daylight savings time (`true`), always
|
|
627
|
+
# selecting the period observing standard time (`false`), or leaving the
|
|
628
|
+
# ambiguity unresolved (`nil`).
|
|
629
|
+
# @yield [periods] if the `dst` parameter did not resolve an ambiguity, an
|
|
630
|
+
# optional block is yielded to.
|
|
631
|
+
# @yieldparam periods [Array<TimezonePeriod>] an `Array` containing all
|
|
632
|
+
# the {TimezonePeriod}s that still match `local_time` after applying the
|
|
633
|
+
# `dst` parameter.
|
|
634
|
+
# @yieldreturn [Object] to resolve the ambiguity: a chosen {TimezonePeriod}
|
|
635
|
+
# or an `Array` containing a chosen {TimezonePeriod}; to leave the
|
|
636
|
+
# ambiguity unresolved: an empty `Array`, an `Array` containing more than
|
|
637
|
+
# one {TimezonePeriod}, or `nil`.
|
|
638
|
+
# @return [Object] the UTC equivalent of `local_time` as a `Time`,
|
|
639
|
+
# `DateTime` or {Timestamp}.
|
|
640
|
+
# @raise [ArgumentError] if `local_time` is `nil`.
|
|
641
|
+
# @raise [PeriodNotFound] if `local_time` is not valid for the time zone
|
|
642
|
+
# (there is no equivalent UTC time).
|
|
643
|
+
# @raise [AmbiguousTime] if `local_time` was ambiguous for the time zone and
|
|
644
|
+
# the `dst` parameter or block did not resolve the ambiguity.
|
|
645
|
+
def local_to_utc(local_time, dst = Timezone.default_dst)
|
|
646
|
+
raise ArgumentError, 'local_time must be specified' unless local_time
|
|
647
|
+
|
|
648
|
+
Timestamp.for(local_time, :ignore) do |ts|
|
|
649
|
+
period = if block_given?
|
|
650
|
+
period_for_local(ts, dst) {|periods| yield periods }
|
|
467
651
|
else
|
|
468
|
-
|
|
652
|
+
period_for_local(ts, dst)
|
|
469
653
|
end
|
|
470
|
-
|
|
471
|
-
period.
|
|
472
|
-
|
|
654
|
+
|
|
655
|
+
ts.add_and_set_utc_offset(-period.observed_utc_offset, :utc)
|
|
656
|
+
end
|
|
473
657
|
end
|
|
474
|
-
|
|
475
|
-
#
|
|
476
|
-
#
|
|
477
|
-
#
|
|
658
|
+
|
|
659
|
+
# Creates a `Time` object based on the given (Gregorian calendar) date and
|
|
660
|
+
# time parameters. The parameters are interpreted as a local time in the
|
|
661
|
+
# time zone. The result has the appropriate `utc_offset`, `zone` and
|
|
662
|
+
# {TimeWithOffset#timezone_offset timezone_offset}.
|
|
478
663
|
#
|
|
479
|
-
#
|
|
480
|
-
#
|
|
481
|
-
#
|
|
664
|
+
# _Warning:_ There are time values that are not valid as local times in a
|
|
665
|
+
# time zone (for example, during the transition from standard time to
|
|
666
|
+
# daylight savings time). There are also time values that are ambiguous,
|
|
667
|
+
# occurring more than once with different offsets to UTC (for example,
|
|
668
|
+
# during the transition from daylight savings time to standard time).
|
|
482
669
|
#
|
|
483
|
-
#
|
|
484
|
-
#
|
|
670
|
+
# In the first case (an invalid local time), a {PeriodNotFound} exception
|
|
671
|
+
# will be raised.
|
|
485
672
|
#
|
|
486
|
-
#
|
|
673
|
+
# In the second case (more than one occurrence), an {AmbiguousTime}
|
|
674
|
+
# exception will be raised unless the optional `dst` parameter or block
|
|
675
|
+
# handles the ambiguity.
|
|
487
676
|
#
|
|
488
|
-
#
|
|
489
|
-
#
|
|
677
|
+
# If the ambiguity is due to a transition from daylight savings time to
|
|
678
|
+
# standard time, the `dst` parameter can be used to select whether the
|
|
679
|
+
# daylight savings time or local time is used. For example, the following
|
|
680
|
+
# code would raise an {AmbiguousTime} exception:
|
|
681
|
+
#
|
|
682
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
|
683
|
+
# tz.local_time(2004,10,31,1,30,0,0)
|
|
684
|
+
#
|
|
685
|
+
# Specifying `dst = true` would return a `Time` with a UTC offset of -4
|
|
686
|
+
# hours and abbreviation EDT (Eastern Daylight Time). Specifying `dst =
|
|
687
|
+
# false` would return a `Time` with a UTC offset of -5 hours and
|
|
688
|
+
# abbreviation EST (Eastern Standard Time).
|
|
689
|
+
#
|
|
690
|
+
# The `dst` parameter will not be able to resolve an ambiguity resulting
|
|
691
|
+
# from the clocks being set back without changing from daylight savings time
|
|
692
|
+
# to standard time. In this case, if a block is specified, it will be called
|
|
693
|
+
# to resolve the ambiguity. The block must take a single parameter - an
|
|
694
|
+
# `Array` of {TimezonePeriod}s that need to be resolved. The block can
|
|
695
|
+
# select and return a single {TimezonePeriod} or return `nil` or an empty
|
|
696
|
+
# `Array` to cause an {AmbiguousTime} exception to be raised.
|
|
490
697
|
#
|
|
491
|
-
#
|
|
492
|
-
#
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
698
|
+
# The default value of the `dst` parameter can be specified using
|
|
699
|
+
# {Timezone.default_dst=}.
|
|
700
|
+
#
|
|
701
|
+
# @param year [Integer] the year.
|
|
702
|
+
# @param month [Integer] the month (1-12).
|
|
703
|
+
# @param day [Integer] the day of the month (1-31).
|
|
704
|
+
# @param hour [Integer] the hour (0-23).
|
|
705
|
+
# @param minute [Integer] the minute (0-59).
|
|
706
|
+
# @param second [Integer] the second (0-59).
|
|
707
|
+
# @param sub_second [Numeric] the fractional part of the second as either
|
|
708
|
+
# a `Rational` that is greater than or equal to 0 and less than 1, or
|
|
709
|
+
# the `Integer` 0.
|
|
710
|
+
# @param dst [Boolean] whether to resolve ambiguous local times by always
|
|
711
|
+
# selecting the period observing daylight savings time (`true`), always
|
|
712
|
+
# selecting the period observing standard time (`false`), or leaving the
|
|
713
|
+
# ambiguity unresolved (`nil`).
|
|
714
|
+
# @yield [periods] if the `dst` parameter did not resolve an ambiguity, an
|
|
715
|
+
# optional block is yielded to.
|
|
716
|
+
# @yieldparam periods [Array<TimezonePeriod>] an `Array` containing all
|
|
717
|
+
# the {TimezonePeriod}s that still match `local_time` after applying the
|
|
718
|
+
# `dst` parameter.
|
|
719
|
+
# @yieldreturn [Object] to resolve the ambiguity: a chosen {TimezonePeriod}
|
|
720
|
+
# or an `Array` containing a chosen {TimezonePeriod}; to leave the
|
|
721
|
+
# ambiguity unresolved: an empty `Array`, an `Array` containing more than
|
|
722
|
+
# one {TimezonePeriod}, or `nil`.
|
|
723
|
+
# @return [TimeWithOffset] a new `Time` object based on the given values,
|
|
724
|
+
# interpreted as a local time in the time zone.
|
|
725
|
+
# @raise [ArgumentError] if either of `year`, `month`, `day`, `hour`,
|
|
726
|
+
# `minute`, or `second` is not an `Integer`.
|
|
727
|
+
# @raise [ArgumentError] if `sub_second` is not a `Rational`, or the
|
|
728
|
+
# `Integer` 0.
|
|
729
|
+
# @raise [ArgumentError] if `utc_offset` is not `nil`, not an `Integer`
|
|
730
|
+
# and not the `Symbol` `:utc`.
|
|
731
|
+
# @raise [RangeError] if `month` is not between 1 and 12.
|
|
732
|
+
# @raise [RangeError] if `day` is not between 1 and 31.
|
|
733
|
+
# @raise [RangeError] if `hour` is not between 0 and 23.
|
|
734
|
+
# @raise [RangeError] if `minute` is not between 0 and 59.
|
|
735
|
+
# @raise [RangeError] if `second` is not between 0 and 59.
|
|
736
|
+
# @raise [RangeError] if `sub_second` is a `Rational` but that is less
|
|
737
|
+
# than 0 or greater than or equal to 1.
|
|
738
|
+
# @raise [PeriodNotFound] if the date and time parameters do not specify a
|
|
739
|
+
# valid local time in the time zone.
|
|
740
|
+
# @raise [AmbiguousTime] if the date and time parameters are ambiguous for
|
|
741
|
+
# the time zone and the `dst` parameter or block did not resolve the
|
|
742
|
+
# ambiguity.
|
|
743
|
+
def local_time(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, sub_second = 0, dst = Timezone.default_dst, &block)
|
|
744
|
+
local_timestamp(year, month, day, hour, minute, second, sub_second, dst, &block).to_time
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
# Creates a `DateTime` object based on the given (Gregorian calendar) date
|
|
748
|
+
# and time parameters. The parameters are interpreted as a local time in the
|
|
749
|
+
# time zone. The result has the appropriate `offset` and
|
|
750
|
+
# {DateTimeWithOffset#timezone_offset timezone_offset}.
|
|
751
|
+
#
|
|
752
|
+
# _Warning:_ There are time values that are not valid as local times in a
|
|
753
|
+
# time zone (for example, during the transition from standard time to
|
|
754
|
+
# daylight savings time). There are also time values that are ambiguous,
|
|
755
|
+
# occurring more than once with different offsets to UTC (for example,
|
|
756
|
+
# during the transition from daylight savings time to standard time).
|
|
757
|
+
#
|
|
758
|
+
# In the first case (an invalid local time), a {PeriodNotFound} exception
|
|
759
|
+
# will be raised.
|
|
760
|
+
#
|
|
761
|
+
# In the second case (more than one occurrence), an {AmbiguousTime}
|
|
762
|
+
# exception will be raised unless the optional `dst` parameter or block
|
|
763
|
+
# handles the ambiguity.
|
|
764
|
+
#
|
|
765
|
+
# If the ambiguity is due to a transition from daylight savings time to
|
|
766
|
+
# standard time, the `dst` parameter can be used to select whether the
|
|
767
|
+
# daylight savings time or local time is used. For example, the following
|
|
768
|
+
# code would raise an {AmbiguousTime} exception:
|
|
769
|
+
#
|
|
770
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
|
771
|
+
# tz.local_datetime(2004,10,31,1,30,0,0)
|
|
772
|
+
#
|
|
773
|
+
# Specifying `dst = true` would return a `Time` with a UTC offset of -4
|
|
774
|
+
# hours and abbreviation EDT (Eastern Daylight Time). Specifying `dst =
|
|
775
|
+
# false` would return a `Time` with a UTC offset of -5 hours and
|
|
776
|
+
# abbreviation EST (Eastern Standard Time).
|
|
777
|
+
#
|
|
778
|
+
# The `dst` parameter will not be able to resolve an ambiguity resulting
|
|
779
|
+
# from the clocks being set back without changing from daylight savings time
|
|
780
|
+
# to standard time. In this case, if a block is specified, it will be called
|
|
781
|
+
# to resolve the ambiguity. The block must take a single parameter - an
|
|
782
|
+
# `Array` of {TimezonePeriod}s that need to be resolved. The block can
|
|
783
|
+
# select and return a single {TimezonePeriod} or return `nil` or an empty
|
|
784
|
+
# `Array` to cause an {AmbiguousTime} exception to be raised.
|
|
785
|
+
#
|
|
786
|
+
# The default value of the `dst` parameter can be specified using
|
|
787
|
+
# {Timezone.default_dst=}.
|
|
788
|
+
#
|
|
789
|
+
# @param year [Integer] the year.
|
|
790
|
+
# @param month [Integer] the month (1-12).
|
|
791
|
+
# @param day [Integer] the day of the month (1-31).
|
|
792
|
+
# @param hour [Integer] the hour (0-23).
|
|
793
|
+
# @param minute [Integer] the minute (0-59).
|
|
794
|
+
# @param second [Integer] the second (0-59).
|
|
795
|
+
# @param sub_second [Numeric] the fractional part of the second as either
|
|
796
|
+
# a `Rational` that is greater than or equal to 0 and less than 1, or
|
|
797
|
+
# the `Integer` 0.
|
|
798
|
+
# @param dst [Boolean] whether to resolve ambiguous local times by always
|
|
799
|
+
# selecting the period observing daylight savings time (`true`), always
|
|
800
|
+
# selecting the period observing standard time (`false`), or leaving the
|
|
801
|
+
# ambiguity unresolved (`nil`).
|
|
802
|
+
# @yield [periods] if the `dst` parameter did not resolve an ambiguity, an
|
|
803
|
+
# optional block is yielded to.
|
|
804
|
+
# @yieldparam periods [Array<TimezonePeriod>] an `Array` containing all
|
|
805
|
+
# the {TimezonePeriod}s that still match `local_time` after applying the
|
|
806
|
+
# `dst` parameter.
|
|
807
|
+
# @yieldreturn [Object] to resolve the ambiguity: a chosen {TimezonePeriod}
|
|
808
|
+
# or an `Array` containing a chosen {TimezonePeriod}; to leave the
|
|
809
|
+
# ambiguity unresolved: an empty `Array`, an `Array` containing more than
|
|
810
|
+
# one {TimezonePeriod}, or `nil`.
|
|
811
|
+
# @return [DateTimeWithOffset] a new `DateTime` object based on the given
|
|
812
|
+
# values, interpreted as a local time in the time zone.
|
|
813
|
+
# @raise [ArgumentError] if either of `year`, `month`, `day`, `hour`,
|
|
814
|
+
# `minute`, or `second` is not an `Integer`.
|
|
815
|
+
# @raise [ArgumentError] if `sub_second` is not a `Rational`, or the
|
|
816
|
+
# `Integer` 0.
|
|
817
|
+
# @raise [ArgumentError] if `utc_offset` is not `nil`, not an `Integer`
|
|
818
|
+
# and not the `Symbol` `:utc`.
|
|
819
|
+
# @raise [RangeError] if `month` is not between 1 and 12.
|
|
820
|
+
# @raise [RangeError] if `day` is not between 1 and 31.
|
|
821
|
+
# @raise [RangeError] if `hour` is not between 0 and 23.
|
|
822
|
+
# @raise [RangeError] if `minute` is not between 0 and 59.
|
|
823
|
+
# @raise [RangeError] if `second` is not between 0 and 59.
|
|
824
|
+
# @raise [RangeError] if `sub_second` is a `Rational` but that is less
|
|
825
|
+
# than 0 or greater than or equal to 1.
|
|
826
|
+
# @raise [PeriodNotFound] if the date and time parameters do not specify a
|
|
827
|
+
# valid local time in the time zone.
|
|
828
|
+
# @raise [AmbiguousTime] if the date and time parameters are ambiguous for
|
|
829
|
+
# the time zone and the `dst` parameter or block did not resolve the
|
|
830
|
+
# ambiguity.
|
|
831
|
+
def local_datetime(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, sub_second = 0, dst = Timezone.default_dst, &block)
|
|
832
|
+
local_timestamp(year, month, day, hour, minute, second, sub_second, dst, &block).to_datetime
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
# Creates a {Timestamp} object based on the given (Gregorian calendar) date
|
|
836
|
+
# and time parameters. The parameters are interpreted as a local time in the
|
|
837
|
+
# time zone. The result has the appropriate {Timestamp#utc_offset
|
|
838
|
+
# utc_offset} and {TimestampWithOffset#timezone_offset timezone_offset}.
|
|
839
|
+
#
|
|
840
|
+
# _Warning:_ There are time values that are not valid as local times in a
|
|
841
|
+
# time zone (for example, during the transition from standard time to
|
|
842
|
+
# daylight savings time). There are also time values that are ambiguous,
|
|
843
|
+
# occurring more than once with different offsets to UTC (for example,
|
|
844
|
+
# during the transition from daylight savings time to standard time).
|
|
845
|
+
#
|
|
846
|
+
# In the first case (an invalid local time), a {PeriodNotFound} exception
|
|
847
|
+
# will be raised.
|
|
848
|
+
#
|
|
849
|
+
# In the second case (more than one occurrence), an {AmbiguousTime}
|
|
850
|
+
# exception will be raised unless the optional `dst` parameter or block
|
|
851
|
+
# handles the ambiguity.
|
|
852
|
+
#
|
|
853
|
+
# If the ambiguity is due to a transition from daylight savings time to
|
|
854
|
+
# standard time, the `dst` parameter can be used to select whether the
|
|
855
|
+
# daylight savings time or local time is used. For example, the following
|
|
856
|
+
# code would raise an {AmbiguousTime} exception:
|
|
857
|
+
#
|
|
858
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
|
859
|
+
# tz.local_timestamp(2004,10,31,1,30,0,0)
|
|
860
|
+
#
|
|
861
|
+
# Specifying `dst = true` would return a `Time` with a UTC offset of -4
|
|
862
|
+
# hours and abbreviation EDT (Eastern Daylight Time). Specifying `dst =
|
|
863
|
+
# false` would return a `Time` with a UTC offset of -5 hours and
|
|
864
|
+
# abbreviation EST (Eastern Standard Time).
|
|
865
|
+
#
|
|
866
|
+
# The `dst` parameter will not be able to resolve an ambiguity resulting
|
|
867
|
+
# from the clocks being set back without changing from daylight savings time
|
|
868
|
+
# to standard time. In this case, if a block is specified, it will be called
|
|
869
|
+
# to resolve the ambiguity. The block must take a single parameter - an
|
|
870
|
+
# `Array` of {TimezonePeriod}s that need to be resolved. The block can
|
|
871
|
+
# select and return a single {TimezonePeriod} or return `nil` or an empty
|
|
872
|
+
# `Array` to cause an {AmbiguousTime} exception to be raised.
|
|
873
|
+
#
|
|
874
|
+
# The default value of the `dst` parameter can be specified using
|
|
875
|
+
# {Timezone.default_dst=}.
|
|
876
|
+
#
|
|
877
|
+
# @param year [Integer] the year.
|
|
878
|
+
# @param month [Integer] the month (1-12).
|
|
879
|
+
# @param day [Integer] the day of the month (1-31).
|
|
880
|
+
# @param hour [Integer] the hour (0-23).
|
|
881
|
+
# @param minute [Integer] the minute (0-59).
|
|
882
|
+
# @param second [Integer] the second (0-59).
|
|
883
|
+
# @param sub_second [Numeric] the fractional part of the second as either
|
|
884
|
+
# a `Rational` that is greater than or equal to 0 and less than 1, or
|
|
885
|
+
# the `Integer` 0.
|
|
886
|
+
# @param dst [Boolean] whether to resolve ambiguous local times by always
|
|
887
|
+
# selecting the period observing daylight savings time (`true`), always
|
|
888
|
+
# selecting the period observing standard time (`false`), or leaving the
|
|
889
|
+
# ambiguity unresolved (`nil`).
|
|
890
|
+
# @yield [periods] if the `dst` parameter did not resolve an ambiguity, an
|
|
891
|
+
# optional block is yielded to.
|
|
892
|
+
# @yieldparam periods [Array<TimezonePeriod>] an `Array` containing all
|
|
893
|
+
# the {TimezonePeriod}s that still match `local_time` after applying the
|
|
894
|
+
# `dst` parameter.
|
|
895
|
+
# @yieldreturn [Object] to resolve the ambiguity: a chosen {TimezonePeriod}
|
|
896
|
+
# or an `Array` containing a chosen {TimezonePeriod}; to leave the
|
|
897
|
+
# ambiguity unresolved: an empty `Array`, an `Array` containing more than
|
|
898
|
+
# one {TimezonePeriod}, or `nil`.
|
|
899
|
+
# @return [TimestampWithOffset] a new {Timestamp} object based on the given
|
|
900
|
+
# values, interpreted as a local time in the time zone.
|
|
901
|
+
# @raise [ArgumentError] if either of `year`, `month`, `day`, `hour`,
|
|
902
|
+
# `minute`, or `second` is not an `Integer`.
|
|
903
|
+
# @raise [ArgumentError] if `sub_second` is not a `Rational`, or the
|
|
904
|
+
# `Integer` 0.
|
|
905
|
+
# @raise [ArgumentError] if `utc_offset` is not `nil`, not an `Integer`
|
|
906
|
+
# and not the `Symbol` `:utc`.
|
|
907
|
+
# @raise [RangeError] if `month` is not between 1 and 12.
|
|
908
|
+
# @raise [RangeError] if `day` is not between 1 and 31.
|
|
909
|
+
# @raise [RangeError] if `hour` is not between 0 and 23.
|
|
910
|
+
# @raise [RangeError] if `minute` is not between 0 and 59.
|
|
911
|
+
# @raise [RangeError] if `second` is not between 0 and 59.
|
|
912
|
+
# @raise [RangeError] if `sub_second` is a `Rational` but that is less
|
|
913
|
+
# than 0 or greater than or equal to 1.
|
|
914
|
+
# @raise [PeriodNotFound] if the date and time parameters do not specify a
|
|
915
|
+
# valid local time in the time zone.
|
|
916
|
+
# @raise [AmbiguousTime] if the date and time parameters are ambiguous for
|
|
917
|
+
# the time zone and the `dst` parameter or block did not resolve the
|
|
918
|
+
# ambiguity.
|
|
919
|
+
def local_timestamp(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, sub_second = 0, dst = Timezone.default_dst, &block)
|
|
920
|
+
ts = Timestamp.create(year, month, day, hour, minute, second, sub_second)
|
|
921
|
+
timezone_offset = period_for_local(ts, dst, &block).offset
|
|
922
|
+
utc_offset = timezone_offset.observed_utc_offset
|
|
923
|
+
TimestampWithOffset.new(ts.value - utc_offset, sub_second, utc_offset).set_timezone_offset(timezone_offset)
|
|
924
|
+
end
|
|
925
|
+
|
|
926
|
+
# Returns the unique offsets used by the time zone up to a given time (`to`)
|
|
927
|
+
# as an `Array` of {TimezoneOffset} instances.
|
|
928
|
+
#
|
|
929
|
+
# A from time may also be supplied using the `from` parameter. If from is
|
|
930
|
+
# not `nil`, only offsets used from that time onwards will be returned.
|
|
931
|
+
#
|
|
932
|
+
# Comparisons with `to` are exclusive. Comparisons with `from` are
|
|
933
|
+
# inclusive.
|
|
934
|
+
#
|
|
935
|
+
# @param to [Object] a `Time`, `DateTime` or {Timestamp} specifying the
|
|
936
|
+
# latest (exclusive) offset to return.
|
|
937
|
+
# @param from [Object] an optional `Time`, `DateTime` or {Timestamp}
|
|
938
|
+
# specifying the earliest (inclusive) offset to return.
|
|
939
|
+
# @return [Array<TimezoneOffsets>] the offsets that are used earlier than
|
|
940
|
+
# `to` and, if specified, at or later than `from`. Offsets may be returned
|
|
941
|
+
# in any order.
|
|
942
|
+
# @raise [ArgumentError] if `from` is specified and `to` is not greater than
|
|
943
|
+
# `from`.
|
|
944
|
+
# @raise [ArgumentError] is raised if `to` is `nil`.
|
|
945
|
+
# @raise [ArgumentError] if either `to` or `from` is a {Timestamp} with an
|
|
946
|
+
# unspecified offset.
|
|
947
|
+
def offsets_up_to(to, from = nil)
|
|
948
|
+
raise ArgumentError, 'to must be specified' unless to
|
|
949
|
+
|
|
950
|
+
to_timestamp = Timestamp.for(to)
|
|
951
|
+
from_timestamp = from && Timestamp.for(from)
|
|
952
|
+
transitions = transitions_up_to(to_timestamp, from_timestamp)
|
|
953
|
+
|
|
497
954
|
if transitions.empty?
|
|
498
955
|
# No transitions in the range, find the period that covers it.
|
|
499
956
|
|
|
500
|
-
if
|
|
957
|
+
if from_timestamp
|
|
501
958
|
# Use the from date as it is inclusive.
|
|
502
|
-
period =
|
|
959
|
+
period = period_for(from_timestamp)
|
|
503
960
|
else
|
|
504
|
-
#
|
|
505
|
-
#
|
|
506
|
-
|
|
507
|
-
# Subtract 1 hour (since this is one of the cached OffsetRationals).
|
|
508
|
-
# Use add_with_convert so that conversion to DateTime is performed if
|
|
509
|
-
# required.
|
|
510
|
-
period = period_for_utc(utc_to.add_with_convert(-3600))
|
|
961
|
+
# to is exclusive, so this can't be used with period_for. However, any
|
|
962
|
+
# time earlier than to can be used. Subtract 1 hour.
|
|
963
|
+
period = period_for(to_timestamp.add_and_set_utc_offset(-3600, :utc))
|
|
511
964
|
end
|
|
512
|
-
|
|
965
|
+
|
|
513
966
|
[period.offset]
|
|
514
967
|
else
|
|
515
968
|
result = Set.new
|
|
516
|
-
|
|
517
|
-
first = transitions.first
|
|
518
|
-
result << first.previous_offset unless
|
|
519
|
-
|
|
969
|
+
|
|
970
|
+
first = transitions.first
|
|
971
|
+
result << first.previous_offset unless from_timestamp && first.at == from_timestamp
|
|
972
|
+
|
|
520
973
|
transitions.each do |t|
|
|
521
974
|
result << t.offset
|
|
522
975
|
end
|
|
523
|
-
|
|
976
|
+
|
|
524
977
|
result.to_a
|
|
525
978
|
end
|
|
526
979
|
end
|
|
527
|
-
|
|
528
|
-
# Returns the canonical identifier
|
|
980
|
+
|
|
981
|
+
# Returns the canonical identifier of this time zone.
|
|
982
|
+
#
|
|
983
|
+
# This is a shortcut for calling `canonical_zone.identifier`. Please refer
|
|
984
|
+
# to the {canonical_zone} documentation for further information.
|
|
529
985
|
#
|
|
530
|
-
#
|
|
531
|
-
# to the canonical_zone documentation for further information.
|
|
986
|
+
# @return [String] the canonical identifier of this time zone.
|
|
532
987
|
def canonical_identifier
|
|
533
988
|
canonical_zone.identifier
|
|
534
989
|
end
|
|
535
|
-
|
|
536
|
-
#
|
|
990
|
+
|
|
991
|
+
# @return [TimeWithOffset] the current local time in the time zone.
|
|
537
992
|
def now
|
|
538
|
-
|
|
993
|
+
to_local(Time.now)
|
|
539
994
|
end
|
|
540
|
-
|
|
541
|
-
#
|
|
995
|
+
|
|
996
|
+
# @return [TimezonePeriod] the current {TimezonePeriod} for the time zone.
|
|
542
997
|
def current_period
|
|
543
|
-
|
|
544
|
-
end
|
|
545
|
-
|
|
546
|
-
# Returns the current
|
|
547
|
-
#
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
# The formatting is identical to Time.strftime and DateTime.strftime, except
|
|
560
|
-
# %Z and %z are replaced with the timezone abbreviation (for example, EST or
|
|
561
|
-
# EDT) and offset for the specified Timezone and time.
|
|
562
|
-
#
|
|
563
|
-
# The offset can be formatted as follows:
|
|
564
|
-
#
|
|
565
|
-
# - %z - hour and minute (e.g. +0500)
|
|
566
|
-
# - %:z - hour and minute separated with a colon (e.g. +05:00)
|
|
567
|
-
# - %::z - hour minute and second separated with colons (e.g. +05:00:00)
|
|
568
|
-
# - %:::z - hour only (e.g. +05)
|
|
569
|
-
#
|
|
570
|
-
# Timezone#strftime currently handles the replacement of %z. From TZInfo
|
|
571
|
-
# version 2.0.0, %z will be passed to Time#strftime and DateTime#strftime
|
|
572
|
-
# instead. Some of the formatting options may cease to be available
|
|
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).
|
|
575
|
-
def strftime(format, utc = Time.now.utc)
|
|
576
|
-
utc = TimeOrDateTime.wrap(utc)
|
|
577
|
-
period = period_for_utc(utc)
|
|
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)
|
|
581
|
-
abbreviation = period.abbreviation.to_s.gsub(/%/, '%%')
|
|
582
|
-
|
|
583
|
-
format = format.gsub(/%(%*)([sZ]|:*z)/) do
|
|
584
|
-
if $1.length.odd?
|
|
585
|
-
# Escaped literal percent or series of percents. Pass on to strftime.
|
|
586
|
-
"#$1%#$2"
|
|
587
|
-
elsif $2 == "s"
|
|
588
|
-
"#$1#{utc.to_i}"
|
|
589
|
-
elsif $2 == "Z"
|
|
590
|
-
"#$1#{abbreviation}"
|
|
591
|
-
else
|
|
592
|
-
m, s = period.utc_total_offset.divmod(60)
|
|
593
|
-
h, m = m.divmod(60)
|
|
594
|
-
case $2.length
|
|
595
|
-
when 1
|
|
596
|
-
"#$1#{'%+03d%02d' % [h,m]}"
|
|
597
|
-
when 2
|
|
598
|
-
"#$1#{'%+03d:%02d' % [h,m]}"
|
|
599
|
-
when 3
|
|
600
|
-
"#$1#{'%+03d:%02d:%02d' % [h,m,s]}"
|
|
601
|
-
when 4
|
|
602
|
-
"#$1#{'%+03d' % [h]}"
|
|
603
|
-
else # more than 3 colons - not a valid option
|
|
604
|
-
# Passing the invalid format string through to Time#strftime or
|
|
605
|
-
# DateTime#strtime would normally result in it being returned in the
|
|
606
|
-
# result. However, with Ruby 1.8.7 on Windows (as tested with Ruby
|
|
607
|
-
# 1.8.7-p374 from https://rubyinstaller.org/downloads/archives),
|
|
608
|
-
# this causes Time#strftime to always return an empty string (e.g.
|
|
609
|
-
# Time.now.strftime('a %::::z b') returns '').
|
|
610
|
-
#
|
|
611
|
-
# Escape the percent to force it to be evaluated as a literal.
|
|
612
|
-
"#$1%%#$2"
|
|
613
|
-
end
|
|
614
|
-
end
|
|
998
|
+
period_for(Time.now)
|
|
999
|
+
end
|
|
1000
|
+
|
|
1001
|
+
# Returns the current local time and {TimezonePeriod} for the time zone as
|
|
1002
|
+
# an `Array`. The first element is the time as a {TimeWithOffset}. The
|
|
1003
|
+
# second element is the period.
|
|
1004
|
+
#
|
|
1005
|
+
# @return [Array] an `Array` containing the current {TimeWithOffset} for the
|
|
1006
|
+
# time zone as the first element and the current {TimezonePeriod} for the
|
|
1007
|
+
# time zone as the second element.
|
|
1008
|
+
def current_time_and_period
|
|
1009
|
+
period = nil
|
|
1010
|
+
|
|
1011
|
+
local_time = Timestamp.for(Time.now) do |ts|
|
|
1012
|
+
period = period_for(ts)
|
|
1013
|
+
TimestampWithOffset.set_timezone_offset(ts, period.offset)
|
|
615
1014
|
end
|
|
616
|
-
|
|
617
|
-
|
|
1015
|
+
|
|
1016
|
+
[local_time, period]
|
|
618
1017
|
end
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
#
|
|
1018
|
+
alias current_period_and_time current_time_and_period
|
|
1019
|
+
|
|
1020
|
+
# Converts a time to local time for the time zone and returns a `String`
|
|
1021
|
+
# representation of the local time according to the given format.
|
|
1022
|
+
#
|
|
1023
|
+
# `Timezone#strftime` first expands any occurrences of `%Z` in the format
|
|
1024
|
+
# string to the time zone abbreviation for the local time (for example, EST
|
|
1025
|
+
# or EDT). Depending on the type of `time` parameter, the result of the
|
|
1026
|
+
# expansion is then passed to either `Time#strftime`, `DateTime#strftime` or
|
|
1027
|
+
# `Timestamp#strftime` to handle any other format directives.
|
|
1028
|
+
#
|
|
1029
|
+
# This method is equivalent to the following:
|
|
622
1030
|
#
|
|
623
|
-
#
|
|
1031
|
+
# time_zone.to_local(time).strftime(format)
|
|
1032
|
+
#
|
|
1033
|
+
# @param format [String] the format string.
|
|
1034
|
+
# @param time [Object] a `Time`, `DateTime` or `Timestamp`.
|
|
1035
|
+
# @return [String] the formatted local time.
|
|
1036
|
+
# @raise [ArgumentError] if `format` or `time` is `nil`.
|
|
1037
|
+
# @raise [ArgumentError] if `time` is a {Timestamp} with an unspecified UTC
|
|
1038
|
+
# offset.
|
|
1039
|
+
def strftime(format, time = Time.now)
|
|
1040
|
+
to_local(time).strftime(format)
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
# @param time [Object] a `Time`, `DateTime` or `Timestamp`.
|
|
1044
|
+
# @return [String] the abbreviation of this {Timezone} at the given time.
|
|
1045
|
+
# @raise [ArgumentError] if `time` is `nil`.
|
|
1046
|
+
# @raise [ArgumentError] if `time` is a {Timestamp} with an unspecified UTC
|
|
1047
|
+
# offset.
|
|
1048
|
+
def abbreviation(time = Time.now)
|
|
1049
|
+
period_for(time).abbreviation
|
|
1050
|
+
end
|
|
1051
|
+
alias abbr abbreviation
|
|
1052
|
+
|
|
1053
|
+
# @param time [Object] a `Time`, `DateTime` or `Timestamp`.
|
|
1054
|
+
# @return [Boolean] whether daylight savings time is in effect at the given
|
|
1055
|
+
# time.
|
|
1056
|
+
# @raise [ArgumentError] if `time` is `nil`.
|
|
1057
|
+
# @raise [ArgumentError] if `time` is a {Timestamp} with an unspecified UTC
|
|
1058
|
+
# offset.
|
|
1059
|
+
def dst?(time = Time.now)
|
|
1060
|
+
period_for(time).dst?
|
|
1061
|
+
end
|
|
1062
|
+
|
|
1063
|
+
# Returns the base offset from UTC in seconds at the given time. This does
|
|
1064
|
+
# not include any adjustment made for daylight savings time and will
|
|
1065
|
+
# typically remain constant throughout the year.
|
|
1066
|
+
#
|
|
1067
|
+
# To obtain the observed offset from UTC, including the effect of daylight
|
|
1068
|
+
# savings time, use {observed_utc_offset} instead.
|
|
1069
|
+
#
|
|
1070
|
+
# If you require accurate {base_utc_offset} values, you should install the
|
|
1071
|
+
# tzinfo-data gem and set {DataSources::RubyDataSource} as the {DataSource}.
|
|
1072
|
+
# When using {DataSources::ZoneinfoDataSource}, the value of
|
|
1073
|
+
# {base_utc_offset} has to be derived from changes to the observed UTC
|
|
1074
|
+
# offset and DST status since it is not included in zoneinfo files.
|
|
1075
|
+
#
|
|
1076
|
+
# @param time [Object] a `Time`, `DateTime` or `Timestamp`.
|
|
1077
|
+
# @return [Integer] the base offset from UTC in seconds at the given time.
|
|
1078
|
+
# @raise [ArgumentError] if `time` is `nil`.
|
|
1079
|
+
# @raise [ArgumentError] if `time` is a {Timestamp} with an unspecified UTC
|
|
1080
|
+
# offset.
|
|
1081
|
+
def base_utc_offset(time = Time.now)
|
|
1082
|
+
period_for(time).base_utc_offset
|
|
1083
|
+
end
|
|
1084
|
+
|
|
1085
|
+
# Returns the observed offset from UTC in seconds at the given time. This
|
|
1086
|
+
# includes adjustments made for daylight savings time.
|
|
1087
|
+
#
|
|
1088
|
+
# @param time [Object] a `Time`, `DateTime` or `Timestamp`.
|
|
1089
|
+
# @return [Integer] the observed offset from UTC in seconds at the given
|
|
1090
|
+
# time.
|
|
1091
|
+
# @raise [ArgumentError] if `time` is `nil`.
|
|
1092
|
+
# @raise [ArgumentError] if `time` is a {Timestamp} with an unspecified UTC
|
|
1093
|
+
# offset.
|
|
1094
|
+
def observed_utc_offset(time = Time.now)
|
|
1095
|
+
period_for(time).observed_utc_offset
|
|
1096
|
+
end
|
|
1097
|
+
alias utc_offset observed_utc_offset
|
|
1098
|
+
|
|
1099
|
+
# Compares this {Timezone} with another based on the {identifier}.
|
|
1100
|
+
#
|
|
1101
|
+
# @param tz [Object] an `Object` to compare this {Timezone} with.
|
|
1102
|
+
# @return [Integer] -1 if `tz` is less than `self`, 0 if `tz` is equal to
|
|
1103
|
+
# `self` and +1 if `tz` is greater than `self`, or `nil` if `tz` is not an
|
|
1104
|
+
# instance of {Timezone}.
|
|
624
1105
|
def <=>(tz)
|
|
625
1106
|
return nil unless tz.is_a?(Timezone)
|
|
626
1107
|
identifier <=> tz.identifier
|
|
627
1108
|
end
|
|
628
1109
|
|
|
629
|
-
#
|
|
630
|
-
#
|
|
1110
|
+
# @param tz [Object] an `Object` to compare this {Timezone} with.
|
|
1111
|
+
# @return [Boolean] `true` if `tz` is an instance of {Timezone} and has the
|
|
1112
|
+
# same {identifier} as `self`, otherwise `false`.
|
|
631
1113
|
def eql?(tz)
|
|
632
1114
|
self == tz
|
|
633
1115
|
end
|
|
634
|
-
|
|
635
|
-
#
|
|
1116
|
+
|
|
1117
|
+
# @return [Integer] a hash based on the {identifier}.
|
|
636
1118
|
def hash
|
|
637
1119
|
identifier.hash
|
|
638
1120
|
end
|
|
639
|
-
|
|
640
|
-
#
|
|
1121
|
+
|
|
1122
|
+
# Returns a serialized representation of this {Timezone}. This method is
|
|
1123
|
+
# called when using `Marshal.dump` with an instance of {Timezone}.
|
|
1124
|
+
#
|
|
1125
|
+
# @param limit [Integer] the maximum depth to dump - ignored.
|
|
1126
|
+
# @return [String] a serialized representation of this {Timezone}.
|
|
641
1127
|
def _dump(limit)
|
|
642
1128
|
identifier
|
|
643
1129
|
end
|
|
644
|
-
|
|
645
|
-
# Loads a
|
|
1130
|
+
|
|
1131
|
+
# Loads a {Timezone} from the serialized representation returned by {_dump}.
|
|
1132
|
+
# This is method is called when using `Marshal.load` or `Marshal.restore`
|
|
1133
|
+
# to restore a serialized {Timezone}.
|
|
1134
|
+
#
|
|
1135
|
+
# @param data [String] a serialized representation of a {Timezone}.
|
|
1136
|
+
# @return [Timezone] the result of converting `data` back into a {Timezone}.
|
|
646
1137
|
def self._load(data)
|
|
647
1138
|
Timezone.get(data)
|
|
648
1139
|
end
|
|
649
|
-
|
|
1140
|
+
|
|
650
1141
|
private
|
|
651
|
-
# Initializes @@loaded_zones.
|
|
652
|
-
def self.init_loaded_zones
|
|
653
|
-
@@loaded_zones = ThreadSafe::Cache.new
|
|
654
|
-
end
|
|
655
|
-
init_loaded_zones
|
|
656
|
-
|
|
657
|
-
# Returns an array of proxies corresponding to the given array of
|
|
658
|
-
# identifiers.
|
|
659
|
-
def self.get_proxies(identifiers)
|
|
660
|
-
identifiers.collect {|identifier| get_proxy(identifier)}
|
|
661
|
-
end
|
|
662
|
-
|
|
663
|
-
# Returns the current DataSource.
|
|
664
|
-
def self.data_source
|
|
665
|
-
DataSource.get
|
|
666
|
-
end
|
|
667
1142
|
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
1143
|
+
# Raises an {UnknownTimezone} exception.
|
|
1144
|
+
#
|
|
1145
|
+
# @raise [UnknownTimezone] always.
|
|
1146
|
+
def raise_unknown_timezone
|
|
1147
|
+
raise UnknownTimezone, 'TZInfo::Timezone should not be constructed directly (use TZInfo::Timezone.get instead)'
|
|
1148
|
+
end
|
|
1149
|
+
end
|
|
673
1150
|
end
|