tzinfo 1.2.11 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.yardopts +3 -0
- data/CHANGES.md +469 -431
- data/LICENSE +13 -13
- data/README.md +368 -114
- data/lib/tzinfo/country.rb +131 -129
- data/lib/tzinfo/country_timezone.rb +70 -112
- data/lib/tzinfo/data_source.rb +389 -144
- data/lib/tzinfo/data_sources/constant_offset_data_timezone_info.rb +56 -0
- data/lib/tzinfo/data_sources/country_info.rb +42 -0
- data/lib/tzinfo/data_sources/data_timezone_info.rb +91 -0
- data/lib/tzinfo/data_sources/linked_timezone_info.rb +33 -0
- data/lib/tzinfo/data_sources/ruby_data_source.rb +141 -0
- data/lib/tzinfo/data_sources/timezone_info.rb +47 -0
- data/lib/tzinfo/data_sources/transitions_data_timezone_info.rb +214 -0
- data/lib/tzinfo/data_sources/zoneinfo_data_source.rb +573 -0
- data/lib/tzinfo/data_sources/zoneinfo_reader.rb +284 -0
- data/lib/tzinfo/data_sources.rb +8 -0
- data/lib/tzinfo/data_timezone.rb +33 -47
- data/lib/tzinfo/datetime_with_offset.rb +153 -0
- data/lib/tzinfo/format1/country_definer.rb +17 -0
- data/lib/tzinfo/format1/country_index_definition.rb +64 -0
- data/lib/tzinfo/format1/timezone_definer.rb +64 -0
- data/lib/tzinfo/format1/timezone_definition.rb +39 -0
- data/lib/tzinfo/format1/timezone_index_definition.rb +77 -0
- data/lib/tzinfo/format1.rb +10 -0
- data/lib/tzinfo/format2/country_definer.rb +68 -0
- data/lib/tzinfo/format2/country_index_definer.rb +68 -0
- data/lib/tzinfo/format2/country_index_definition.rb +46 -0
- data/lib/tzinfo/format2/timezone_definer.rb +94 -0
- data/lib/tzinfo/format2/timezone_definition.rb +73 -0
- data/lib/tzinfo/format2/timezone_index_definer.rb +45 -0
- data/lib/tzinfo/format2/timezone_index_definition.rb +55 -0
- data/lib/tzinfo/format2.rb +10 -0
- data/lib/tzinfo/info_timezone.rb +26 -21
- data/lib/tzinfo/linked_timezone.rb +33 -52
- data/lib/tzinfo/offset_timezone_period.rb +42 -0
- data/lib/tzinfo/string_deduper.rb +118 -0
- data/lib/tzinfo/time_with_offset.rb +128 -0
- data/lib/tzinfo/timestamp.rb +548 -0
- data/lib/tzinfo/timestamp_with_offset.rb +85 -0
- data/lib/tzinfo/timezone.rb +979 -502
- data/lib/tzinfo/timezone_offset.rb +84 -74
- data/lib/tzinfo/timezone_period.rb +151 -217
- data/lib/tzinfo/timezone_proxy.rb +70 -79
- data/lib/tzinfo/timezone_transition.rb +77 -109
- data/lib/tzinfo/transitions_timezone_period.rb +63 -0
- data/lib/tzinfo/version.rb +7 -0
- data/lib/tzinfo/with_offset.rb +61 -0
- data/lib/tzinfo.rb +60 -40
- data.tar.gz.sig +0 -0
- metadata +51 -115
- metadata.gz.sig +2 -3
- data/Rakefile +0 -107
- data/lib/tzinfo/annual_rules.rb +0 -51
- data/lib/tzinfo/country_index_definition.rb +0 -31
- data/lib/tzinfo/country_info.rb +0 -42
- data/lib/tzinfo/data_timezone_info.rb +0 -55
- data/lib/tzinfo/linked_timezone_info.rb +0 -26
- data/lib/tzinfo/offset_rationals.rb +0 -77
- data/lib/tzinfo/posix_time_zone_parser.rb +0 -136
- data/lib/tzinfo/ruby_core_support.rb +0 -176
- data/lib/tzinfo/ruby_country_info.rb +0 -74
- data/lib/tzinfo/ruby_data_source.rb +0 -136
- data/lib/tzinfo/time_or_datetime.rb +0 -351
- data/lib/tzinfo/timezone_definition.rb +0 -36
- data/lib/tzinfo/timezone_index_definition.rb +0 -54
- data/lib/tzinfo/timezone_info.rb +0 -30
- data/lib/tzinfo/timezone_transition_definition.rb +0 -104
- data/lib/tzinfo/transition_data_timezone_info.rb +0 -274
- data/lib/tzinfo/transition_rule.rb +0 -325
- data/lib/tzinfo/zoneinfo_country_info.rb +0 -37
- data/lib/tzinfo/zoneinfo_data_source.rb +0 -504
- data/lib/tzinfo/zoneinfo_timezone_info.rb +0 -516
- data/test/assets/payload.rb +0 -1
- data/test/tc_annual_rules.rb +0 -95
- data/test/tc_country.rb +0 -240
- data/test/tc_country_index_definition.rb +0 -69
- data/test/tc_country_info.rb +0 -16
- data/test/tc_country_timezone.rb +0 -173
- data/test/tc_data_source.rb +0 -218
- data/test/tc_data_timezone.rb +0 -99
- data/test/tc_data_timezone_info.rb +0 -18
- data/test/tc_info_timezone.rb +0 -34
- data/test/tc_linked_timezone.rb +0 -155
- data/test/tc_linked_timezone_info.rb +0 -23
- data/test/tc_offset_rationals.rb +0 -23
- data/test/tc_posix_time_zone_parser.rb +0 -261
- data/test/tc_ruby_core_support.rb +0 -168
- data/test/tc_ruby_country_info.rb +0 -110
- data/test/tc_ruby_data_source.rb +0 -175
- data/test/tc_time_or_datetime.rb +0 -674
- data/test/tc_timezone.rb +0 -1361
- data/test/tc_timezone_definition.rb +0 -113
- data/test/tc_timezone_index_definition.rb +0 -73
- data/test/tc_timezone_info.rb +0 -11
- data/test/tc_timezone_london.rb +0 -143
- data/test/tc_timezone_melbourne.rb +0 -142
- data/test/tc_timezone_new_york.rb +0 -142
- data/test/tc_timezone_offset.rb +0 -126
- data/test/tc_timezone_period.rb +0 -555
- data/test/tc_timezone_proxy.rb +0 -136
- data/test/tc_timezone_transition.rb +0 -366
- data/test/tc_timezone_transition_definition.rb +0 -295
- data/test/tc_timezone_utc.rb +0 -27
- data/test/tc_transition_data_timezone_info.rb +0 -433
- data/test/tc_transition_rule.rb +0 -663
- data/test/tc_zoneinfo_country_info.rb +0 -78
- data/test/tc_zoneinfo_data_source.rb +0 -1226
- data/test/tc_zoneinfo_timezone_info.rb +0 -2149
- data/test/test_utils.rb +0 -214
- data/test/ts_all.rb +0 -7
- data/test/ts_all_ruby.rb +0 -5
- data/test/ts_all_zoneinfo.rb +0 -9
- data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +0 -89
- data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +0 -327
- data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +0 -230
- data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +0 -19
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +0 -21
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +0 -21
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +0 -21
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +0 -273
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +0 -198
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +0 -333
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +0 -277
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +0 -235
- data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +0 -16
- data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +0 -940
- data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +0 -609
- data/test/tzinfo-data/tzinfo/data/version.rb +0 -20
- data/test/tzinfo-data/tzinfo/data.rb +0 -8
- data/test/zoneinfo/America/Argentina/Buenos_Aires +0 -0
- data/test/zoneinfo/America/New_York +0 -0
- data/test/zoneinfo/Australia/Melbourne +0 -0
- data/test/zoneinfo/EST +0 -0
- data/test/zoneinfo/Etc/UTC +0 -0
- data/test/zoneinfo/Europe/Amsterdam +0 -0
- data/test/zoneinfo/Europe/Andorra +0 -0
- data/test/zoneinfo/Europe/London +0 -0
- data/test/zoneinfo/Europe/Paris +0 -0
- data/test/zoneinfo/Europe/Prague +0 -0
- data/test/zoneinfo/Factory +0 -0
- data/test/zoneinfo/iso3166.tab +0 -274
- data/test/zoneinfo/leapseconds +0 -78
- data/test/zoneinfo/posix/Europe/London +0 -0
- data/test/zoneinfo/posixrules +0 -0
- data/test/zoneinfo/right/Europe/London +0 -0
- data/test/zoneinfo/zone.tab +0 -452
- data/test/zoneinfo/zone1970.tab +0 -384
- data/tzinfo.gemspec +0 -21
|
@@ -1,63 +1,44 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
1
3
|
module TZInfo
|
|
4
|
+
# Represents time zones that are defined as a link to or alias for another
|
|
5
|
+
# time zone.
|
|
6
|
+
class LinkedTimezone < InfoTimezone
|
|
7
|
+
# Initializes a new {LinkedTimezone}.
|
|
8
|
+
#
|
|
9
|
+
# {LinkedTimezone} instances should not normally be created directly. Use
|
|
10
|
+
# the {Timezone.get} method to obtain {Timezone} instances.
|
|
11
|
+
#
|
|
12
|
+
# @param info [DataSources::LinkedTimezoneInfo] a
|
|
13
|
+
# {DataSources::LinkedTimezoneInfo} instance supplied by a {DataSource}
|
|
14
|
+
# that will be used as the source of data for this {LinkedTimezone}.
|
|
15
|
+
def initialize(info)
|
|
16
|
+
super
|
|
17
|
+
@linked_timezone = Timezone.get(info.link_to_identifier)
|
|
18
|
+
end
|
|
2
19
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class LinkedTimezone < InfoTimezone #:nodoc:
|
|
7
|
-
# Returns the TimezonePeriod for the given UTC time. utc can either be
|
|
8
|
-
# a DateTime, Time or integer timestamp (Time.to_i). Any timezone
|
|
9
|
-
# information in utc is ignored (it is treated as a UTC time).
|
|
10
|
-
#
|
|
11
|
-
# If no TimezonePeriod could be found, PeriodNotFound is raised.
|
|
12
|
-
def period_for_utc(utc)
|
|
13
|
-
@linked_timezone.period_for_utc(utc)
|
|
20
|
+
# (see Timezone#period_for)
|
|
21
|
+
def period_for(time)
|
|
22
|
+
@linked_timezone.period_for(time)
|
|
14
23
|
end
|
|
15
|
-
|
|
16
|
-
#
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
# Raises PeriodNotFound if no periods are found for the given time.
|
|
20
|
-
def periods_for_local(local)
|
|
21
|
-
@linked_timezone.periods_for_local(local)
|
|
24
|
+
|
|
25
|
+
# (see Timezone#periods_for_local)
|
|
26
|
+
def periods_for_local(local_time)
|
|
27
|
+
@linked_timezone.periods_for_local(local_time)
|
|
22
28
|
end
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# Transitions are returned up to a given date and time up to a given date
|
|
28
|
-
# and time, specified in UTC (utc_to).
|
|
29
|
-
#
|
|
30
|
-
# A from date and time may also be supplied using the utc_from parameter
|
|
31
|
-
# (also specified in UTC). If utc_from is not nil, only transitions from
|
|
32
|
-
# that date and time onwards will be returned.
|
|
33
|
-
#
|
|
34
|
-
# Comparisons with utc_to are exclusive. Comparisons with utc_from are
|
|
35
|
-
# inclusive. If a transition falls precisely on utc_to, it will be excluded.
|
|
36
|
-
# If a transition falls on utc_from, it will be included.
|
|
37
|
-
#
|
|
38
|
-
# Transitions returned are ordered by when they occur, from earliest to
|
|
39
|
-
# latest.
|
|
40
|
-
#
|
|
41
|
-
# utc_to and utc_from can be specified using either DateTime, Time or
|
|
42
|
-
# integer timestamps (Time.to_i).
|
|
43
|
-
#
|
|
44
|
-
# If utc_from is specified and utc_to is not greater than utc_from, then
|
|
45
|
-
# transitions_up_to raises an ArgumentError exception.
|
|
46
|
-
def transitions_up_to(utc_to, utc_from = nil)
|
|
47
|
-
@linked_timezone.transitions_up_to(utc_to, utc_from)
|
|
29
|
+
|
|
30
|
+
# (see Timezone#transitions_up_to)
|
|
31
|
+
def transitions_up_to(to, from = nil)
|
|
32
|
+
@linked_timezone.transitions_up_to(to, from)
|
|
48
33
|
end
|
|
49
|
-
|
|
50
|
-
# Returns the canonical
|
|
34
|
+
|
|
35
|
+
# Returns the canonical {Timezone} instance for this {LinkedTimezone}.
|
|
36
|
+
#
|
|
37
|
+
# For a {LinkedTimezone}, this is the canonical zone of the link target.
|
|
51
38
|
#
|
|
52
|
-
#
|
|
39
|
+
# @return [Timezone] the canonical {Timezone} instance for this {Timezone}.
|
|
53
40
|
def canonical_zone
|
|
54
41
|
@linked_timezone.canonical_zone
|
|
55
42
|
end
|
|
56
|
-
|
|
57
|
-
protected
|
|
58
|
-
def setup(info)
|
|
59
|
-
super(info)
|
|
60
|
-
@linked_timezone = Timezone.get(info.link_to_identifier)
|
|
61
|
-
end
|
|
62
43
|
end
|
|
63
44
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
module TZInfo
|
|
4
|
+
# Represents the infinite period of time in a time zone that constantly
|
|
5
|
+
# observes the same offset from UTC (has an unbounded start and end).
|
|
6
|
+
class OffsetTimezonePeriod < TimezonePeriod
|
|
7
|
+
# Initializes an {OffsetTimezonePeriod}.
|
|
8
|
+
#
|
|
9
|
+
# @param offset [TimezoneOffset] the offset that is constantly observed.
|
|
10
|
+
# @raise [ArgumentError] if `offset` is `nil`.
|
|
11
|
+
def initialize(offset)
|
|
12
|
+
super
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @return [TimezoneTransition] the transition that defines the start of this
|
|
16
|
+
# {TimezonePeriod}, always `nil` for {OffsetTimezonePeriod}.
|
|
17
|
+
def start_transition
|
|
18
|
+
nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [TimezoneTransition] the transition that defines the end of this
|
|
22
|
+
# {TimezonePeriod}, always `nil` for {OffsetTimezonePeriod}.
|
|
23
|
+
def end_transition
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Determines if this {OffsetTimezonePeriod} is equal to another instance.
|
|
28
|
+
#
|
|
29
|
+
# @param p [Object] the instance to test for equality.
|
|
30
|
+
# @return [Boolean] `true` if `p` is a {OffsetTimezonePeriod} with the same
|
|
31
|
+
# {offset}, otherwise `false`.
|
|
32
|
+
def ==(p)
|
|
33
|
+
p.kind_of?(OffsetTimezonePeriod) && offset == p.offset
|
|
34
|
+
end
|
|
35
|
+
alias eql? ==
|
|
36
|
+
|
|
37
|
+
# @return [Integer] a hash based on {offset}.
|
|
38
|
+
def hash
|
|
39
|
+
offset.hash
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'concurrent'
|
|
5
|
+
|
|
6
|
+
module TZInfo
|
|
7
|
+
# Maintains a pool of `String` instances. The {#dedupe} method will return
|
|
8
|
+
# either a pooled copy of a given `String` or add the instance to the pool.
|
|
9
|
+
#
|
|
10
|
+
# @private
|
|
11
|
+
class StringDeduper #:nodoc:
|
|
12
|
+
class << self
|
|
13
|
+
# @return [StringDeduper] a globally available singleton instance of
|
|
14
|
+
# {StringDeduper}. This instance is safe for use in concurrently
|
|
15
|
+
# executing threads.
|
|
16
|
+
attr_reader :global
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Initializes a new {StringDeduper}.
|
|
20
|
+
def initialize
|
|
21
|
+
@strings = create_hash do |h, k|
|
|
22
|
+
v = k.dup.freeze
|
|
23
|
+
h[v] = v
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param string [String] the string to deduplicate.
|
|
28
|
+
# @return [bool] `string` if it is frozen, otherwise a frozen, possibly
|
|
29
|
+
# pre-existing copy of `string`.
|
|
30
|
+
def dedupe(string)
|
|
31
|
+
return string if string.frozen?
|
|
32
|
+
@strings[string]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
# Creates a `Hash` to store pooled `String` instances.
|
|
38
|
+
#
|
|
39
|
+
# @param block [Proc] Default value block to be passed to `Hash.new`.
|
|
40
|
+
# @return [Hash] a `Hash` to store pooled `String` instances.
|
|
41
|
+
def create_hash(&block)
|
|
42
|
+
Hash.new(&block)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
private_constant :StringDeduper
|
|
46
|
+
|
|
47
|
+
# A thread-safe version of {StringDeduper}.
|
|
48
|
+
#
|
|
49
|
+
# @private
|
|
50
|
+
class ConcurrentStringDeduper < StringDeduper #:nodoc:
|
|
51
|
+
protected
|
|
52
|
+
|
|
53
|
+
def create_hash(&block)
|
|
54
|
+
Concurrent::Map.new(&block)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
private_constant :ConcurrentStringDeduper
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
string_unary_minus_does_dedupe = if '0'.respond_to?(:-@)
|
|
61
|
+
# :nocov_no_string_-@:
|
|
62
|
+
s1 = -('0'.dup)
|
|
63
|
+
s2 = -('0'.dup)
|
|
64
|
+
s1.object_id == s2.object_id
|
|
65
|
+
# :nocov_no_string_-@:
|
|
66
|
+
else
|
|
67
|
+
# :nocov_string_-@:
|
|
68
|
+
false
|
|
69
|
+
# :nocov_string_-@:
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
if string_unary_minus_does_dedupe
|
|
73
|
+
# :nocov_no_deduping_string_unary_minus:
|
|
74
|
+
|
|
75
|
+
# An implementation of {StringDeduper} using the `String#-@` method where
|
|
76
|
+
# that method performs deduplication (Ruby 2.5 and later).
|
|
77
|
+
#
|
|
78
|
+
# Note that this is slightly different to the plain {StringDeduper}
|
|
79
|
+
# implementation. In this implementation, frozen literal strings are already
|
|
80
|
+
# in the pool and are candidates for being returned, even when passed
|
|
81
|
+
# another equal frozen non-literal string. {StringDeduper} will always
|
|
82
|
+
# return frozen strings.
|
|
83
|
+
#
|
|
84
|
+
# There are also differences in encoding handling. This implementation will
|
|
85
|
+
# treat strings with different encodings as different strings.
|
|
86
|
+
# {StringDeduper} will treat strings with the compatible encodings as the
|
|
87
|
+
# same string.
|
|
88
|
+
#
|
|
89
|
+
# @private
|
|
90
|
+
class UnaryMinusGlobalStringDeduper #:nodoc:
|
|
91
|
+
# @param string [String] the string to deduplicate.
|
|
92
|
+
# @return [bool] `string` if it is frozen, otherwise a frozen, possibly
|
|
93
|
+
# pre-existing copy of `string`.
|
|
94
|
+
def dedupe(string)
|
|
95
|
+
# String#-@ on Ruby 2.6 will dedupe a frozen non-literal String. Ruby
|
|
96
|
+
# 2.5 will just return frozen strings.
|
|
97
|
+
#
|
|
98
|
+
# The pooled implementation can't tell the difference between frozen
|
|
99
|
+
# literals and frozen non-literals, so must always return frozen String
|
|
100
|
+
# instances to avoid doing unncessary work when loading format 2
|
|
101
|
+
# TZInfo::Data modules.
|
|
102
|
+
#
|
|
103
|
+
# For compatibility with the pooled implementation, just return frozen
|
|
104
|
+
# string instances (acting like Ruby 2.5).
|
|
105
|
+
return string if string.frozen?
|
|
106
|
+
-string
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
private_constant :UnaryMinusGlobalStringDeduper
|
|
110
|
+
|
|
111
|
+
StringDeduper.instance_variable_set(:@global, UnaryMinusGlobalStringDeduper.new)
|
|
112
|
+
# :nocov_no_deduping_string_unary_minus:
|
|
113
|
+
else
|
|
114
|
+
# :nocov_deduping_string_unary_minus:
|
|
115
|
+
StringDeduper.instance_variable_set(:@global, ConcurrentStringDeduper.new)
|
|
116
|
+
# :nocov_deduping_string_unary_minus:
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
module TZInfo
|
|
5
|
+
# A subclass of `Time` used to represent local times. {TimeWithOffset} holds a
|
|
6
|
+
# reference to the related {TimezoneOffset} and overrides various methods to
|
|
7
|
+
# return results appropriate for the {TimezoneOffset}. Certain operations will
|
|
8
|
+
# clear the associated {TimezoneOffset} (if the {TimezoneOffset} would not
|
|
9
|
+
# necessarily be valid for the result). Once the {TimezoneOffset} has been
|
|
10
|
+
# cleared, {TimeWithOffset} behaves identically to `Time`.
|
|
11
|
+
#
|
|
12
|
+
# Arithmetic performed on {TimeWithOffset} instances is _not_ time zone-aware.
|
|
13
|
+
# Regardless of whether transitions in the time zone are crossed, results of
|
|
14
|
+
# arithmetic operations will always maintain the same offset from UTC
|
|
15
|
+
# (`utc_offset`). The associated {TimezoneOffset} will aways be cleared.
|
|
16
|
+
class TimeWithOffset < Time
|
|
17
|
+
include WithOffset
|
|
18
|
+
|
|
19
|
+
# @return [TimezoneOffset] the {TimezoneOffset} associated with this
|
|
20
|
+
# instance.
|
|
21
|
+
attr_reader :timezone_offset
|
|
22
|
+
|
|
23
|
+
# Marks this {TimeWithOffset} as a local time with the UTC offset of a given
|
|
24
|
+
# {TimezoneOffset} and sets the associated {TimezoneOffset}.
|
|
25
|
+
#
|
|
26
|
+
# @param timezone_offset [TimezoneOffset] the {TimezoneOffset} to use to set
|
|
27
|
+
# the offset of this {TimeWithOffset}.
|
|
28
|
+
# @return [TimeWithOffset] `self`.
|
|
29
|
+
# @raise [ArgumentError] if `timezone_offset` is `nil`.
|
|
30
|
+
def set_timezone_offset(timezone_offset)
|
|
31
|
+
raise ArgumentError, 'timezone_offset must be specified' unless timezone_offset
|
|
32
|
+
localtime(timezone_offset.observed_utc_offset)
|
|
33
|
+
@timezone_offset = timezone_offset
|
|
34
|
+
self
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# An overridden version of `Time#dst?` that, if there is an associated
|
|
38
|
+
# {TimezoneOffset}, returns the result of calling {TimezoneOffset#dst? dst?}
|
|
39
|
+
# on that offset.
|
|
40
|
+
#
|
|
41
|
+
# @return [Boolean] `true` if daylight savings time is being observed,
|
|
42
|
+
# otherwise `false`.
|
|
43
|
+
def dst?
|
|
44
|
+
to = timezone_offset
|
|
45
|
+
to ? to.dst? : super
|
|
46
|
+
end
|
|
47
|
+
alias isdst dst?
|
|
48
|
+
|
|
49
|
+
# An overridden version of `Time#gmtime` that clears the associated
|
|
50
|
+
# {TimezoneOffset}.
|
|
51
|
+
#
|
|
52
|
+
# @return [TimeWithOffset] `self`.
|
|
53
|
+
def gmtime
|
|
54
|
+
super
|
|
55
|
+
@timezone_offset = nil
|
|
56
|
+
self
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# An overridden version of `Time#localtime` that clears the associated
|
|
60
|
+
# {TimezoneOffset}.
|
|
61
|
+
#
|
|
62
|
+
# @return [TimeWithOffset] `self`.
|
|
63
|
+
def localtime(*args)
|
|
64
|
+
super
|
|
65
|
+
@timezone_offset = nil
|
|
66
|
+
self
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# An overridden version of `Time#round` that, if there is an associated
|
|
70
|
+
# {TimezoneOffset}, returns a {TimeWithOffset} preserving that offset.
|
|
71
|
+
#
|
|
72
|
+
# @return [Time] the rounded time.
|
|
73
|
+
def round(ndigits = 0)
|
|
74
|
+
if_timezone_offset(super) {|o,t| self.class.at(t.to_i, t.subsec * 1_000_000).set_timezone_offset(o) }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# An overridden version of `Time#to_a`. The `isdst` (index 8) and `zone`
|
|
78
|
+
# (index 9) elements of the array are set according to the associated
|
|
79
|
+
# {TimezoneOffset}.
|
|
80
|
+
#
|
|
81
|
+
# @return [Array] an `Array` representation of the {TimeWithOffset}.
|
|
82
|
+
def to_a
|
|
83
|
+
if_timezone_offset(super) do |o,a|
|
|
84
|
+
a[8] = o.dst?
|
|
85
|
+
a[9] = o.abbreviation
|
|
86
|
+
a
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# An overridden version of `Time#utc` that clears the associated
|
|
91
|
+
# {TimezoneOffset}.
|
|
92
|
+
#
|
|
93
|
+
# @return [TimeWithOffset] `self`.
|
|
94
|
+
def utc
|
|
95
|
+
super
|
|
96
|
+
@timezone_offset = nil
|
|
97
|
+
self
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# An overridden version of `Time#zone` that, if there is an associated
|
|
101
|
+
# {TimezoneOffset}, returns the {TimezoneOffset#abbreviation abbreviation}
|
|
102
|
+
# of that offset.
|
|
103
|
+
#
|
|
104
|
+
# @return [String] the {TimezoneOffset#abbreviation abbreviation} of the
|
|
105
|
+
# associated {TimezoneOffset}, or the result from `Time#zone` if there is
|
|
106
|
+
# no such offset.
|
|
107
|
+
def zone
|
|
108
|
+
to = timezone_offset
|
|
109
|
+
to ? to.abbreviation : super
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# An overridden version of `Time#to_datetime` that, if there is an
|
|
113
|
+
# associated {TimezoneOffset}, returns a {DateTimeWithOffset} with that
|
|
114
|
+
# offset.
|
|
115
|
+
#
|
|
116
|
+
# @return [DateTime] if there is an associated {TimezoneOffset}, a
|
|
117
|
+
# {DateTimeWithOffset} representation of this {TimeWithOffset}, otherwise
|
|
118
|
+
# a `Time` representation.
|
|
119
|
+
def to_datetime
|
|
120
|
+
if_timezone_offset(super) do |o,dt|
|
|
121
|
+
offset = dt.offset
|
|
122
|
+
result = DateTimeWithOffset.jd(dt.jd + dt.day_fraction - offset)
|
|
123
|
+
result = result.new_offset(offset) unless offset == 0
|
|
124
|
+
result.set_timezone_offset(o)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|