tzinfo 1.2.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of tzinfo might be problematic. Click here for more details.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +0 -0
- data/.yardopts +6 -0
- data/CHANGES.md +786 -0
- data/LICENSE +19 -0
- data/README.md +151 -0
- data/Rakefile +107 -0
- data/lib/tzinfo.rb +40 -0
- data/lib/tzinfo/country.rb +196 -0
- data/lib/tzinfo/country_index_definition.rb +31 -0
- data/lib/tzinfo/country_info.rb +42 -0
- data/lib/tzinfo/country_timezone.rb +135 -0
- data/lib/tzinfo/data_source.rb +190 -0
- data/lib/tzinfo/data_timezone.rb +58 -0
- data/lib/tzinfo/data_timezone_info.rb +55 -0
- data/lib/tzinfo/info_timezone.rb +30 -0
- data/lib/tzinfo/linked_timezone.rb +63 -0
- data/lib/tzinfo/linked_timezone_info.rb +26 -0
- data/lib/tzinfo/offset_rationals.rb +77 -0
- data/lib/tzinfo/ruby_core_support.rb +146 -0
- data/lib/tzinfo/ruby_country_info.rb +74 -0
- data/lib/tzinfo/ruby_data_source.rb +136 -0
- data/lib/tzinfo/time_or_datetime.rb +340 -0
- data/lib/tzinfo/timezone.rb +669 -0
- data/lib/tzinfo/timezone_definition.rb +36 -0
- data/lib/tzinfo/timezone_index_definition.rb +54 -0
- data/lib/tzinfo/timezone_info.rb +30 -0
- data/lib/tzinfo/timezone_offset.rb +101 -0
- data/lib/tzinfo/timezone_period.rb +245 -0
- data/lib/tzinfo/timezone_proxy.rb +105 -0
- data/lib/tzinfo/timezone_transition.rb +130 -0
- data/lib/tzinfo/timezone_transition_definition.rb +104 -0
- data/lib/tzinfo/transition_data_timezone_info.rb +274 -0
- data/lib/tzinfo/zoneinfo_country_info.rb +37 -0
- data/lib/tzinfo/zoneinfo_data_source.rb +488 -0
- data/lib/tzinfo/zoneinfo_timezone_info.rb +296 -0
- data/test/tc_country.rb +234 -0
- data/test/tc_country_index_definition.rb +69 -0
- data/test/tc_country_info.rb +16 -0
- data/test/tc_country_timezone.rb +173 -0
- data/test/tc_data_source.rb +218 -0
- data/test/tc_data_timezone.rb +99 -0
- data/test/tc_data_timezone_info.rb +18 -0
- data/test/tc_info_timezone.rb +34 -0
- data/test/tc_linked_timezone.rb +155 -0
- data/test/tc_linked_timezone_info.rb +23 -0
- data/test/tc_offset_rationals.rb +23 -0
- data/test/tc_ruby_core_support.rb +168 -0
- data/test/tc_ruby_country_info.rb +110 -0
- data/test/tc_ruby_data_source.rb +143 -0
- data/test/tc_time_or_datetime.rb +654 -0
- data/test/tc_timezone.rb +1350 -0
- data/test/tc_timezone_definition.rb +113 -0
- data/test/tc_timezone_index_definition.rb +73 -0
- data/test/tc_timezone_info.rb +11 -0
- data/test/tc_timezone_london.rb +143 -0
- data/test/tc_timezone_melbourne.rb +142 -0
- data/test/tc_timezone_new_york.rb +142 -0
- data/test/tc_timezone_offset.rb +126 -0
- data/test/tc_timezone_period.rb +555 -0
- data/test/tc_timezone_proxy.rb +136 -0
- data/test/tc_timezone_transition.rb +366 -0
- data/test/tc_timezone_transition_definition.rb +295 -0
- data/test/tc_timezone_utc.rb +27 -0
- data/test/tc_transition_data_timezone_info.rb +423 -0
- data/test/tc_zoneinfo_country_info.rb +78 -0
- data/test/tc_zoneinfo_data_source.rb +1195 -0
- data/test/tc_zoneinfo_timezone_info.rb +1232 -0
- data/test/test_utils.rb +163 -0
- data/test/ts_all.rb +7 -0
- data/test/ts_all_ruby.rb +5 -0
- data/test/ts_all_zoneinfo.rb +7 -0
- data/test/tzinfo-data/tzinfo/data.rb +8 -0
- data/test/tzinfo-data/tzinfo/data/definitions/America/Argentina/Buenos_Aires.rb +89 -0
- data/test/tzinfo-data/tzinfo/data/definitions/America/New_York.rb +315 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Australia/Melbourne.rb +218 -0
- data/test/tzinfo-data/tzinfo/data/definitions/EST.rb +19 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__m__1.rb +21 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/GMT__p__1.rb +21 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Etc/UTC.rb +21 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Amsterdam.rb +261 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Andorra.rb +186 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/London.rb +321 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Paris.rb +265 -0
- data/test/tzinfo-data/tzinfo/data/definitions/Europe/Prague.rb +220 -0
- data/test/tzinfo-data/tzinfo/data/definitions/UTC.rb +16 -0
- data/test/tzinfo-data/tzinfo/data/indexes/countries.rb +927 -0
- data/test/tzinfo-data/tzinfo/data/indexes/timezones.rb +596 -0
- data/test/tzinfo-data/tzinfo/data/version.rb +14 -0
- 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 +275 -0
- data/test/zoneinfo/leapseconds +61 -0
- 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 +439 -0
- data/test/zoneinfo/zone1970.tab +369 -0
- data/tzinfo.gemspec +21 -0
- metadata +193 -0
- metadata.gz.sig +2 -0
@@ -0,0 +1,136 @@
|
|
1
|
+
module TZInfo
|
2
|
+
# A DataSource that loads data from the set of Ruby modules included in the
|
3
|
+
# TZInfo::Data library (tzinfo-data gem).
|
4
|
+
#
|
5
|
+
# To have TZInfo use this DataSource, call TZInfo::DataSource.set as follows:
|
6
|
+
#
|
7
|
+
# TZInfo::DataSource.set(:ruby)
|
8
|
+
class RubyDataSource < DataSource
|
9
|
+
# Base path for require.
|
10
|
+
REQUIRE_PATH = File.join('tzinfo', 'data', 'definitions')
|
11
|
+
|
12
|
+
# Whether the timezone index has been loaded yet.
|
13
|
+
@@timezone_index_loaded = false
|
14
|
+
|
15
|
+
# Whether the country index has been loaded yet.
|
16
|
+
@@country_index_loaded = false
|
17
|
+
|
18
|
+
# Returns a TimezoneInfo instance for a given identifier.
|
19
|
+
# Raises InvalidTimezoneIdentifier if the timezone is not found or the
|
20
|
+
# identifier is invalid.
|
21
|
+
def load_timezone_info(identifier)
|
22
|
+
raise InvalidTimezoneIdentifier, 'Invalid identifier' if identifier !~ /^[A-Za-z0-9\+\-_]+(\/[A-Za-z0-9\+\-_]+)*$/
|
23
|
+
|
24
|
+
identifier = identifier.gsub(/-/, '__m__').gsub(/\+/, '__p__')
|
25
|
+
|
26
|
+
# Untaint identifier after it has been reassigned to a new string. We
|
27
|
+
# don't want to modify the original identifier. identifier may also be
|
28
|
+
# frozen and therefore cannot be untainted.
|
29
|
+
identifier.untaint
|
30
|
+
|
31
|
+
identifier = identifier.split('/')
|
32
|
+
begin
|
33
|
+
require_definition(identifier)
|
34
|
+
|
35
|
+
m = Data::Definitions
|
36
|
+
identifier.each {|part|
|
37
|
+
m = m.const_get(part)
|
38
|
+
}
|
39
|
+
|
40
|
+
m.get
|
41
|
+
rescue LoadError, NameError => e
|
42
|
+
raise InvalidTimezoneIdentifier, e.message
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns an array of all the available timezone identifiers.
|
47
|
+
def timezone_identifiers
|
48
|
+
load_timezone_index
|
49
|
+
Data::Indexes::Timezones.timezones
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns an array of all the available timezone identifiers for
|
53
|
+
# data timezones (i.e. those that actually contain definitions).
|
54
|
+
def data_timezone_identifiers
|
55
|
+
load_timezone_index
|
56
|
+
Data::Indexes::Timezones.data_timezones
|
57
|
+
end
|
58
|
+
|
59
|
+
# Returns an array of all the available timezone identifiers that
|
60
|
+
# are links to other timezones.
|
61
|
+
def linked_timezone_identifiers
|
62
|
+
load_timezone_index
|
63
|
+
Data::Indexes::Timezones.linked_timezones
|
64
|
+
end
|
65
|
+
|
66
|
+
# Returns a CountryInfo instance for the given ISO 3166-1 alpha-2
|
67
|
+
# country code. Raises InvalidCountryCode if the country could not be found
|
68
|
+
# or the code is invalid.
|
69
|
+
def load_country_info(code)
|
70
|
+
load_country_index
|
71
|
+
info = Data::Indexes::Countries.countries[code]
|
72
|
+
raise InvalidCountryCode, 'Invalid country code' unless info
|
73
|
+
info
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns an array of all the available ISO 3166-1 alpha-2
|
77
|
+
# country codes.
|
78
|
+
def country_codes
|
79
|
+
load_country_index
|
80
|
+
Data::Indexes::Countries.countries.keys.freeze
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the name of this DataSource.
|
84
|
+
def to_s
|
85
|
+
"Ruby DataSource"
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
# Requires a zone definition by its identifier (split on /).
|
91
|
+
def require_definition(identifier)
|
92
|
+
require_data(*(['definitions'] + identifier))
|
93
|
+
end
|
94
|
+
|
95
|
+
# Requires an index by its name.
|
96
|
+
def self.require_index(name)
|
97
|
+
require_data(*['indexes', name])
|
98
|
+
end
|
99
|
+
|
100
|
+
# Requires a file from tzinfo/data.
|
101
|
+
def require_data(*file)
|
102
|
+
self.class.require_data(*file)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Requires a file from tzinfo/data.
|
106
|
+
def self.require_data(*file)
|
107
|
+
require File.join('tzinfo', 'data', *file)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Loads in the index of timezones if it hasn't already been loaded.
|
111
|
+
def load_timezone_index
|
112
|
+
self.class.load_timezone_index
|
113
|
+
end
|
114
|
+
|
115
|
+
# Loads in the index of timezones if it hasn't already been loaded.
|
116
|
+
def self.load_timezone_index
|
117
|
+
unless @@timezone_index_loaded
|
118
|
+
require_index('timezones')
|
119
|
+
@@timezone_index_loaded = true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Loads in the index of countries if it hasn't already been loaded.
|
124
|
+
def load_country_index
|
125
|
+
self.class.load_country_index
|
126
|
+
end
|
127
|
+
|
128
|
+
# Loads in the index of countries if it hasn't already been loaded.
|
129
|
+
def self.load_country_index
|
130
|
+
unless @@country_index_loaded
|
131
|
+
require_index('countries')
|
132
|
+
@@country_index_loaded = true
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,340 @@
|
|
1
|
+
require 'date'
|
2
|
+
require 'rational' unless defined?(Rational)
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module TZInfo
|
6
|
+
# Used by TZInfo internally to represent either a Time, DateTime or
|
7
|
+
# an Integer timestamp (seconds since 1970-01-01 00:00:00).
|
8
|
+
class TimeOrDateTime
|
9
|
+
include Comparable
|
10
|
+
|
11
|
+
# Constructs a new TimeOrDateTime. timeOrDateTime can be a Time, DateTime
|
12
|
+
# or Integer. If using a Time or DateTime, any time zone information
|
13
|
+
# is ignored.
|
14
|
+
#
|
15
|
+
# Integer timestamps must be within the range supported by Time on the
|
16
|
+
# platform being used.
|
17
|
+
def initialize(timeOrDateTime)
|
18
|
+
@time = nil
|
19
|
+
@datetime = nil
|
20
|
+
@timestamp = nil
|
21
|
+
|
22
|
+
if timeOrDateTime.is_a?(Time)
|
23
|
+
@time = timeOrDateTime
|
24
|
+
|
25
|
+
# Avoid using the slower Rational class unless necessary.
|
26
|
+
nsec = RubyCoreSupport.time_nsec(@time)
|
27
|
+
usec = nsec % 1000 == 0 ? nsec / 1000 : Rational(nsec, 1000)
|
28
|
+
|
29
|
+
@time = Time.utc(@time.year, @time.mon, @time.mday, @time.hour, @time.min, @time.sec, usec) unless @time.utc?
|
30
|
+
@orig = @time
|
31
|
+
elsif timeOrDateTime.is_a?(DateTime)
|
32
|
+
@datetime = timeOrDateTime
|
33
|
+
@datetime = @datetime.new_offset(0) unless @datetime.offset == 0
|
34
|
+
@orig = @datetime
|
35
|
+
else
|
36
|
+
@timestamp = timeOrDateTime.to_i
|
37
|
+
|
38
|
+
if !RubyCoreSupport.time_supports_64bit && (@timestamp > 2147483647 || @timestamp < -2147483648 || (@timestamp < 0 && !RubyCoreSupport.time_supports_negative))
|
39
|
+
raise RangeError, 'Timestamp is outside the supported range of Time on this platform'
|
40
|
+
end
|
41
|
+
|
42
|
+
@orig = @timestamp
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the time as a Time.
|
47
|
+
#
|
48
|
+
# When converting from a DateTime, the result is truncated to microsecond
|
49
|
+
# precision.
|
50
|
+
def to_time
|
51
|
+
# Thread-safety: It is possible that the value of @time may be
|
52
|
+
# calculated multiple times in concurrently executing threads. It is not
|
53
|
+
# worth the overhead of locking to ensure that @time is only
|
54
|
+
# calculated once.
|
55
|
+
|
56
|
+
unless @time
|
57
|
+
result = if @timestamp
|
58
|
+
Time.at(@timestamp).utc
|
59
|
+
else
|
60
|
+
Time.utc(year, mon, mday, hour, min, sec, usec)
|
61
|
+
end
|
62
|
+
|
63
|
+
return result if frozen?
|
64
|
+
@time = result
|
65
|
+
end
|
66
|
+
|
67
|
+
@time
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the time as a DateTime.
|
71
|
+
#
|
72
|
+
# When converting from a Time, the result is truncated to microsecond
|
73
|
+
# precision.
|
74
|
+
def to_datetime
|
75
|
+
# Thread-safety: It is possible that the value of @datetime may be
|
76
|
+
# calculated multiple times in concurrently executing threads. It is not
|
77
|
+
# worth the overhead of locking to ensure that @datetime is only
|
78
|
+
# calculated once.
|
79
|
+
|
80
|
+
unless @datetime
|
81
|
+
# Avoid using Rational unless necessary.
|
82
|
+
u = usec
|
83
|
+
s = u == 0 ? sec : Rational(sec * 1000000 + u, 1000000)
|
84
|
+
result = RubyCoreSupport.datetime_new(year, mon, mday, hour, min, s)
|
85
|
+
return result if frozen?
|
86
|
+
@datetime = result
|
87
|
+
end
|
88
|
+
|
89
|
+
@datetime
|
90
|
+
end
|
91
|
+
|
92
|
+
# Returns the time as an integer timestamp.
|
93
|
+
def to_i
|
94
|
+
# Thread-safety: It is possible that the value of @timestamp may be
|
95
|
+
# calculated multiple times in concurrently executing threads. It is not
|
96
|
+
# worth the overhead of locking to ensure that @timestamp is only
|
97
|
+
# calculated once.
|
98
|
+
|
99
|
+
unless @timestamp
|
100
|
+
result = to_time.to_i
|
101
|
+
return result if frozen?
|
102
|
+
@timestamp = result
|
103
|
+
end
|
104
|
+
|
105
|
+
@timestamp
|
106
|
+
end
|
107
|
+
|
108
|
+
# Returns the time as the original time passed to new.
|
109
|
+
def to_orig
|
110
|
+
@orig
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns a string representation of the TimeOrDateTime.
|
114
|
+
def to_s
|
115
|
+
if @orig.is_a?(Time)
|
116
|
+
"Time: #{@orig.to_s}"
|
117
|
+
elsif @orig.is_a?(DateTime)
|
118
|
+
"DateTime: #{@orig.to_s}"
|
119
|
+
else
|
120
|
+
"Timestamp: #{@orig.to_s}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Returns internal object state as a programmer-readable string.
|
125
|
+
def inspect
|
126
|
+
"#<#{self.class}: #{@orig.inspect}>"
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns the year.
|
130
|
+
def year
|
131
|
+
if @time
|
132
|
+
@time.year
|
133
|
+
elsif @datetime
|
134
|
+
@datetime.year
|
135
|
+
else
|
136
|
+
to_time.year
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns the month of the year (1..12).
|
141
|
+
def mon
|
142
|
+
if @time
|
143
|
+
@time.mon
|
144
|
+
elsif @datetime
|
145
|
+
@datetime.mon
|
146
|
+
else
|
147
|
+
to_time.mon
|
148
|
+
end
|
149
|
+
end
|
150
|
+
alias :month :mon
|
151
|
+
|
152
|
+
# Returns the day of the month (1..n).
|
153
|
+
def mday
|
154
|
+
if @time
|
155
|
+
@time.mday
|
156
|
+
elsif @datetime
|
157
|
+
@datetime.mday
|
158
|
+
else
|
159
|
+
to_time.mday
|
160
|
+
end
|
161
|
+
end
|
162
|
+
alias :day :mday
|
163
|
+
|
164
|
+
# Returns the hour of the day (0..23).
|
165
|
+
def hour
|
166
|
+
if @time
|
167
|
+
@time.hour
|
168
|
+
elsif @datetime
|
169
|
+
@datetime.hour
|
170
|
+
else
|
171
|
+
to_time.hour
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Returns the minute of the hour (0..59).
|
176
|
+
def min
|
177
|
+
if @time
|
178
|
+
@time.min
|
179
|
+
elsif @datetime
|
180
|
+
@datetime.min
|
181
|
+
else
|
182
|
+
to_time.min
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# Returns the second of the minute (0..60). (60 for a leap second).
|
187
|
+
def sec
|
188
|
+
if @time
|
189
|
+
@time.sec
|
190
|
+
elsif @datetime
|
191
|
+
@datetime.sec
|
192
|
+
else
|
193
|
+
to_time.sec
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# Returns the number of microseconds for the time.
|
198
|
+
def usec
|
199
|
+
if @time
|
200
|
+
@time.usec
|
201
|
+
elsif @datetime
|
202
|
+
# Ruby 1.8 has sec_fraction (of which the documentation says
|
203
|
+
# 'I do NOT recommend you to use this method'). sec_fraction no longer
|
204
|
+
# exists in Ruby 1.9.
|
205
|
+
|
206
|
+
# Calculate the sec_fraction from the day_fraction.
|
207
|
+
((@datetime.day_fraction - OffsetRationals.rational_for_offset(@datetime.hour * 3600 + @datetime.min * 60 + @datetime.sec)) * 86400000000).to_i
|
208
|
+
else
|
209
|
+
0
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Compares this TimeOrDateTime with another Time, DateTime, timestamp
|
214
|
+
# (Integer) or TimeOrDateTime. Returns -1, 0 or +1 depending
|
215
|
+
# whether the receiver is less than, equal to, or greater than
|
216
|
+
# timeOrDateTime.
|
217
|
+
#
|
218
|
+
# Returns nil if the passed in timeOrDateTime is not comparable with
|
219
|
+
# TimeOrDateTime instances.
|
220
|
+
#
|
221
|
+
# Comparisons involving a DateTime will be performed using DateTime#<=>.
|
222
|
+
# Comparisons that don't involve a DateTime, but include a Time will be
|
223
|
+
# performed with Time#<=>. Otherwise comparisons will be performed with
|
224
|
+
# Integer#<=>.
|
225
|
+
def <=>(timeOrDateTime)
|
226
|
+
return nil unless timeOrDateTime.is_a?(TimeOrDateTime) ||
|
227
|
+
timeOrDateTime.is_a?(Time) ||
|
228
|
+
timeOrDateTime.is_a?(DateTime) ||
|
229
|
+
timeOrDateTime.respond_to?(:to_i)
|
230
|
+
|
231
|
+
unless timeOrDateTime.is_a?(TimeOrDateTime)
|
232
|
+
timeOrDateTime = TimeOrDateTime.wrap(timeOrDateTime)
|
233
|
+
end
|
234
|
+
|
235
|
+
orig = timeOrDateTime.to_orig
|
236
|
+
|
237
|
+
if @orig.is_a?(DateTime) || orig.is_a?(DateTime)
|
238
|
+
# If either is a DateTime, assume it is there for a reason
|
239
|
+
# (i.e. for its larger range of acceptable values on 32-bit systems).
|
240
|
+
to_datetime <=> timeOrDateTime.to_datetime
|
241
|
+
elsif @orig.is_a?(Time) || orig.is_a?(Time)
|
242
|
+
to_time <=> timeOrDateTime.to_time
|
243
|
+
else
|
244
|
+
to_i <=> timeOrDateTime.to_i
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Adds a number of seconds to the TimeOrDateTime. Returns a new
|
249
|
+
# TimeOrDateTime, preserving what the original constructed type was.
|
250
|
+
# If the original type is a Time and the resulting calculation goes out of
|
251
|
+
# range for Times, then an exception will be raised by the Time class.
|
252
|
+
def +(seconds)
|
253
|
+
if seconds == 0
|
254
|
+
self
|
255
|
+
else
|
256
|
+
if @orig.is_a?(DateTime)
|
257
|
+
TimeOrDateTime.new(@orig + OffsetRationals.rational_for_offset(seconds))
|
258
|
+
else
|
259
|
+
# + defined for Time and Integer
|
260
|
+
TimeOrDateTime.new(@orig + seconds)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Subtracts a number of seconds from the TimeOrDateTime. Returns a new
|
266
|
+
# TimeOrDateTime, preserving what the original constructed type was.
|
267
|
+
# If the original type is a Time and the resulting calculation goes out of
|
268
|
+
# range for Times, then an exception will be raised by the Time class.
|
269
|
+
def -(seconds)
|
270
|
+
self + (-seconds)
|
271
|
+
end
|
272
|
+
|
273
|
+
# Similar to the + operator, but converts to a DateTime based TimeOrDateTime
|
274
|
+
# where the Time or Integer timestamp to go out of the allowed range for a
|
275
|
+
# Time, converts to a DateTime based TimeOrDateTime.
|
276
|
+
#
|
277
|
+
# Note that the range of Time varies based on the platform.
|
278
|
+
def add_with_convert(seconds)
|
279
|
+
if seconds == 0
|
280
|
+
self
|
281
|
+
else
|
282
|
+
if @orig.is_a?(DateTime)
|
283
|
+
TimeOrDateTime.new(@orig + OffsetRationals.rational_for_offset(seconds))
|
284
|
+
else
|
285
|
+
# A Time or timestamp.
|
286
|
+
result = to_i + seconds
|
287
|
+
|
288
|
+
if ((result > 2147483647 || result < -2147483648) && !RubyCoreSupport.time_supports_64bit) || (result < 0 && !RubyCoreSupport.time_supports_negative)
|
289
|
+
result = TimeOrDateTime.new(to_datetime + OffsetRationals.rational_for_offset(seconds))
|
290
|
+
else
|
291
|
+
result = TimeOrDateTime.new(@orig + seconds)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Returns true if todt represents the same time and was originally
|
298
|
+
# constructed with the same type (DateTime, Time or timestamp) as this
|
299
|
+
# TimeOrDateTime.
|
300
|
+
def eql?(todt)
|
301
|
+
todt.kind_of?(TimeOrDateTime) && to_orig.eql?(todt.to_orig)
|
302
|
+
end
|
303
|
+
|
304
|
+
# Returns a hash of this TimeOrDateTime.
|
305
|
+
def hash
|
306
|
+
@orig.hash
|
307
|
+
end
|
308
|
+
|
309
|
+
# If no block is given, returns a TimeOrDateTime wrapping the given
|
310
|
+
# timeOrDateTime. If a block is specified, a TimeOrDateTime is constructed
|
311
|
+
# and passed to the block. The result of the block must be a TimeOrDateTime.
|
312
|
+
#
|
313
|
+
# The result of the block will be converted to the type of the originally
|
314
|
+
# passed in timeOrDateTime and then returned as the result of wrap.
|
315
|
+
#
|
316
|
+
# timeOrDateTime can be a Time, DateTime, timestamp (Integer) or
|
317
|
+
# TimeOrDateTime. If a TimeOrDateTime is passed in, no new TimeOrDateTime
|
318
|
+
# will be constructed and the value passed to wrap will be used when
|
319
|
+
# calling the block.
|
320
|
+
def self.wrap(timeOrDateTime)
|
321
|
+
t = timeOrDateTime.is_a?(TimeOrDateTime) ? timeOrDateTime : TimeOrDateTime.new(timeOrDateTime)
|
322
|
+
|
323
|
+
if block_given?
|
324
|
+
t = yield t
|
325
|
+
|
326
|
+
if timeOrDateTime.is_a?(TimeOrDateTime)
|
327
|
+
t
|
328
|
+
elsif timeOrDateTime.is_a?(Time)
|
329
|
+
t.to_time
|
330
|
+
elsif timeOrDateTime.is_a?(DateTime)
|
331
|
+
t.to_datetime
|
332
|
+
else
|
333
|
+
t.to_i
|
334
|
+
end
|
335
|
+
else
|
336
|
+
t
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|