mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge pull request #28272 from rails/add-iso8601-and-rfc3339-parsing
Add iso8601 and rfc3339 parsing to timezones
This commit is contained in:
commit
de17d9e23d
8 changed files with 398 additions and 0 deletions
|
@ -1,3 +1,81 @@
|
||||||
|
* Add `rfc3339` aliases to `xmlschema` for `Time` and `ActiveSupport::TimeWithZone`
|
||||||
|
|
||||||
|
For naming consistency when using the RFC 3339 profile of ISO 8601 in applications.
|
||||||
|
|
||||||
|
*Andrew White*
|
||||||
|
|
||||||
|
* Add `Time.rfc3339` parsing method
|
||||||
|
|
||||||
|
The `Time.xmlschema` and consequently its alias `iso8601` accepts timestamps
|
||||||
|
without a offset in contravention of the RFC 3339 standard. This method
|
||||||
|
enforces that constraint and raises an `ArgumentError` if it doesn't.
|
||||||
|
|
||||||
|
*Andrew White*
|
||||||
|
|
||||||
|
* Add `ActiveSupport::TimeZone.rfc3339` parsing method
|
||||||
|
|
||||||
|
Previously there was no way to get a RFC 3339 timestamp into a specific
|
||||||
|
timezone without either using `parse` or chaining methods. The new method
|
||||||
|
allows parsing directly into the timezone, e.g:
|
||||||
|
|
||||||
|
>> Time.zone = "Hawaii"
|
||||||
|
=> "Hawaii"
|
||||||
|
>> Time.zone.rfc3339("1999-12-31T14:00:00Z")
|
||||||
|
=> Fri, 31 Dec 1999 14:00:00 HST -10:00
|
||||||
|
|
||||||
|
This new method has stricter semantics than the current `parse` method
|
||||||
|
and will raise an `ArgumentError` instead of returning nil, e.g:
|
||||||
|
|
||||||
|
>> Time.zone = "Hawaii"
|
||||||
|
=> "Hawaii"
|
||||||
|
>> Time.zone.rfc3339("foobar")
|
||||||
|
ArgumentError: invalid date
|
||||||
|
>> Time.zone.parse("foobar")
|
||||||
|
=> nil
|
||||||
|
|
||||||
|
It will also raise an `ArgumentError` when either the time or offset
|
||||||
|
components are missing, e.g:
|
||||||
|
|
||||||
|
>> Time.zone = "Hawaii"
|
||||||
|
=> "Hawaii"
|
||||||
|
>> Time.zone.rfc3339("1999-12-31")
|
||||||
|
ArgumentError: invalid date
|
||||||
|
>> Time.zone.rfc3339("1999-12-31T14:00:00")
|
||||||
|
ArgumentError: invalid date
|
||||||
|
|
||||||
|
*Andrew White*
|
||||||
|
|
||||||
|
* Add `ActiveSupport::TimeZone.iso8601` parsing method
|
||||||
|
|
||||||
|
Previously there was no way to get a ISO 8601 timestamp into a specific
|
||||||
|
timezone without either using `parse` or chaining methods. The new method
|
||||||
|
allows parsing directly into the timezone, e.g:
|
||||||
|
|
||||||
|
>> Time.zone = "Hawaii"
|
||||||
|
=> "Hawaii"
|
||||||
|
>> Time.zone.iso8601("1999-12-31T14:00:00Z")
|
||||||
|
=> Fri, 31 Dec 1999 14:00:00 HST -10:00
|
||||||
|
|
||||||
|
If the timestamp is a ISO 8601 date (YYYY-MM-DD) then the time is set
|
||||||
|
to midnight, e.g:
|
||||||
|
|
||||||
|
>> Time.zone = "Hawaii"
|
||||||
|
=> "Hawaii"
|
||||||
|
>> Time.zone.iso8601("1999-12-31")
|
||||||
|
=> Fri, 31 Dec 1999 00:00:00 HST -10:00
|
||||||
|
|
||||||
|
This new method has stricter semantics than the current `parse` method
|
||||||
|
and will raise an `ArgumentError` instead of returning nil, e.g:
|
||||||
|
|
||||||
|
>> Time.zone = "Hawaii"
|
||||||
|
=> "Hawaii"
|
||||||
|
>> Time.zone.iso8601("foobar")
|
||||||
|
ArgumentError: invalid date
|
||||||
|
>> Time.zone.parse("foobar")
|
||||||
|
=> nil
|
||||||
|
|
||||||
|
*Andrew White*
|
||||||
|
|
||||||
* Deprecate implicit coercion of `ActiveSupport::Duration`
|
* Deprecate implicit coercion of `ActiveSupport::Duration`
|
||||||
|
|
||||||
Currently `ActiveSupport::Duration` implicitly converts to a seconds
|
Currently `ActiveSupport::Duration` implicitly converts to a seconds
|
||||||
|
|
|
@ -53,6 +53,29 @@ class Time
|
||||||
end
|
end
|
||||||
alias_method :at_without_coercion, :at
|
alias_method :at_without_coercion, :at
|
||||||
alias_method :at, :at_with_coercion
|
alias_method :at, :at_with_coercion
|
||||||
|
|
||||||
|
# Creates a +Time+ instance from an RFC 3339 string.
|
||||||
|
#
|
||||||
|
# Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
|
||||||
|
#
|
||||||
|
# If the time or offset components are missing then an +ArgumentError+ will be raised.
|
||||||
|
#
|
||||||
|
# Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
|
||||||
|
def rfc3339(str)
|
||||||
|
parts = Date._rfc3339(str)
|
||||||
|
|
||||||
|
raise ArgumentError, "invalid date" if parts.empty?
|
||||||
|
|
||||||
|
Time.new(
|
||||||
|
parts.fetch(:year),
|
||||||
|
parts.fetch(:mon),
|
||||||
|
parts.fetch(:mday),
|
||||||
|
parts.fetch(:hour),
|
||||||
|
parts.fetch(:min),
|
||||||
|
parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
|
||||||
|
parts.fetch(:offset)
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the number of seconds since 00:00:00.
|
# Returns the number of seconds since 00:00:00.
|
||||||
|
|
|
@ -64,4 +64,7 @@ class Time
|
||||||
def formatted_offset(colon = true, alternate_utc_string = nil)
|
def formatted_offset(colon = true, alternate_utc_string = nil)
|
||||||
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Aliased to +xmlschema+ for compatibility with +DateTime+
|
||||||
|
alias_method :rfc3339, :xmlschema
|
||||||
end
|
end
|
||||||
|
|
|
@ -148,6 +148,7 @@ module ActiveSupport
|
||||||
"#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z'.freeze)}"
|
"#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z'.freeze)}"
|
||||||
end
|
end
|
||||||
alias_method :iso8601, :xmlschema
|
alias_method :iso8601, :xmlschema
|
||||||
|
alias_method :rfc3339, :xmlschema
|
||||||
|
|
||||||
# Coerces time to a string for JSON encoding. The default format is ISO 8601.
|
# Coerces time to a string for JSON encoding. The default format is ISO 8601.
|
||||||
# You can get %Y/%m/%d %H:%M:%S +offset style by setting
|
# You can get %Y/%m/%d %H:%M:%S +offset style by setting
|
||||||
|
|
|
@ -339,6 +339,41 @@ module ActiveSupport
|
||||||
Time.at(secs).utc.in_time_zone(self)
|
Time.at(secs).utc.in_time_zone(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Method for creating new ActiveSupport::TimeWithZone instance in time zone
|
||||||
|
# of +self+ from an ISO 8601 string.
|
||||||
|
#
|
||||||
|
# Time.zone = 'Hawaii' # => "Hawaii"
|
||||||
|
# Time.zone.iso8601('1999-12-31T14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
||||||
|
#
|
||||||
|
# If the time components are missing then they will be set to zero.
|
||||||
|
#
|
||||||
|
# Time.zone = 'Hawaii' # => "Hawaii"
|
||||||
|
# Time.zone.iso8601('1999-12-31') # => Fri, 31 Dec 1999 00:00:00 HST -10:00
|
||||||
|
#
|
||||||
|
# If the string is invalid then an +ArgumentError+ will be raised unlike +parse+
|
||||||
|
# which returns +nil+ when given an invalid date string.
|
||||||
|
def iso8601(str)
|
||||||
|
parts = Date._iso8601(str)
|
||||||
|
|
||||||
|
raise ArgumentError, "invalid date" if parts.empty?
|
||||||
|
|
||||||
|
time = Time.new(
|
||||||
|
parts.fetch(:year),
|
||||||
|
parts.fetch(:mon),
|
||||||
|
parts.fetch(:mday),
|
||||||
|
parts.fetch(:hour, 0),
|
||||||
|
parts.fetch(:min, 0),
|
||||||
|
parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0),
|
||||||
|
parts.fetch(:offset, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
if parts[:offset]
|
||||||
|
TimeWithZone.new(time.utc, self)
|
||||||
|
else
|
||||||
|
TimeWithZone.new(nil, self, time)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# Method for creating new ActiveSupport::TimeWithZone instance in time zone
|
# Method for creating new ActiveSupport::TimeWithZone instance in time zone
|
||||||
# of +self+ from parsed string.
|
# of +self+ from parsed string.
|
||||||
#
|
#
|
||||||
|
@ -359,6 +394,36 @@ module ActiveSupport
|
||||||
parts_to_time(Date._parse(str, false), now)
|
parts_to_time(Date._parse(str, false), now)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Method for creating new ActiveSupport::TimeWithZone instance in time zone
|
||||||
|
# of +self+ from an RFC 3339 string.
|
||||||
|
#
|
||||||
|
# Time.zone = 'Hawaii' # => "Hawaii"
|
||||||
|
# Time.zone.rfc3339('2000-01-01T00:00:00Z') # => Fri, 31 Dec 1999 14:00:00 HST -10:00
|
||||||
|
#
|
||||||
|
# If the time or zone components are missing then an +ArgumentError+ will
|
||||||
|
# be raised. This is much stricter than either +parse+ or +iso8601+ which
|
||||||
|
# allow for missing components.
|
||||||
|
#
|
||||||
|
# Time.zone = 'Hawaii' # => "Hawaii"
|
||||||
|
# Time.zone.rfc3339('1999-12-31') # => ArgumentError: invalid date
|
||||||
|
def rfc3339(str)
|
||||||
|
parts = Date._rfc3339(str)
|
||||||
|
|
||||||
|
raise ArgumentError, "invalid date" if parts.empty?
|
||||||
|
|
||||||
|
time = Time.new(
|
||||||
|
parts.fetch(:year),
|
||||||
|
parts.fetch(:mon),
|
||||||
|
parts.fetch(:mday),
|
||||||
|
parts.fetch(:hour),
|
||||||
|
parts.fetch(:min),
|
||||||
|
parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
|
||||||
|
parts.fetch(:offset)
|
||||||
|
)
|
||||||
|
|
||||||
|
TimeWithZone.new(time.utc, self)
|
||||||
|
end
|
||||||
|
|
||||||
# Parses +str+ according to +format+ and returns an ActiveSupport::TimeWithZone.
|
# Parses +str+ according to +format+ and returns an ActiveSupport::TimeWithZone.
|
||||||
#
|
#
|
||||||
# Assumes that +str+ is a time in the time zone +self+,
|
# Assumes that +str+ is a time in the time zone +self+,
|
||||||
|
|
|
@ -569,6 +569,11 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
|
||||||
Time::DATE_FORMATS.delete(:custom)
|
Time::DATE_FORMATS.delete(:custom)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_with_fractional_seconds
|
||||||
|
time = Time.new(1999, 12, 31, 19, 0, Rational(1, 8), -18000)
|
||||||
|
assert_equal "1999-12-31T19:00:00.125-05:00", time.rfc3339(3)
|
||||||
|
end
|
||||||
|
|
||||||
def test_to_date
|
def test_to_date
|
||||||
assert_equal Date.new(2005, 2, 21), Time.local(2005, 2, 21, 17, 44, 30).to_date
|
assert_equal Date.new(2005, 2, 21), Time.local(2005, 2, 21, 17, 44, 30).to_date
|
||||||
end
|
end
|
||||||
|
@ -910,6 +915,37 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
|
||||||
def test_all_year
|
def test_all_year
|
||||||
assert_equal Time.local(2011, 1, 1, 0, 0, 0)..Time.local(2011, 12, 31, 23, 59, 59, Rational(999999999, 1000)), Time.local(2011, 6, 7, 10, 10, 10).all_year
|
assert_equal Time.local(2011, 1, 1, 0, 0, 0)..Time.local(2011, 12, 31, 23, 59, 59, Rational(999999999, 1000)), Time.local(2011, 6, 7, 10, 10, 10).all_year
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_parse
|
||||||
|
time = Time.rfc3339("1999-12-31T19:00:00.125-05:00")
|
||||||
|
|
||||||
|
assert_equal 1999, time.year
|
||||||
|
assert_equal 12, time.month
|
||||||
|
assert_equal 31, time.day
|
||||||
|
assert_equal 19, time.hour
|
||||||
|
assert_equal 0, time.min
|
||||||
|
assert_equal 0, time.sec
|
||||||
|
assert_equal 125000, time.usec
|
||||||
|
assert_equal(-18000, time.utc_offset)
|
||||||
|
|
||||||
|
exception = assert_raises(ArgumentError) do
|
||||||
|
Time.rfc3339("1999-12-31")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "invalid date", exception.message
|
||||||
|
|
||||||
|
exception = assert_raises(ArgumentError) do
|
||||||
|
Time.rfc3339("1999-12-31T19:00:00")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "invalid date", exception.message
|
||||||
|
|
||||||
|
exception = assert_raises(ArgumentError) do
|
||||||
|
Time.rfc3339("foobar")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "invalid date", exception.message
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class TimeExtMarshalingTest < ActiveSupport::TestCase
|
class TimeExtMarshalingTest < ActiveSupport::TestCase
|
||||||
|
|
|
@ -144,6 +144,16 @@ class TimeWithZoneTest < ActiveSupport::TestCase
|
||||||
assert_equal "1999-12-31T19:00:00-05:00", @twz.xmlschema(nil)
|
assert_equal "1999-12-31T19:00:00-05:00", @twz.xmlschema(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_iso8601_with_fractional_seconds
|
||||||
|
@twz += Rational(1, 8)
|
||||||
|
assert_equal "1999-12-31T19:00:00.125-05:00", @twz.iso8601(3)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_with_fractional_seconds
|
||||||
|
@twz += Rational(1, 8)
|
||||||
|
assert_equal "1999-12-31T19:00:00.125-05:00", @twz.rfc3339(3)
|
||||||
|
end
|
||||||
|
|
||||||
def test_to_yaml
|
def test_to_yaml
|
||||||
yaml = <<-EOF.strip_heredoc
|
yaml = <<-EOF.strip_heredoc
|
||||||
--- !ruby/object:ActiveSupport::TimeWithZone
|
--- !ruby/object:ActiveSupport::TimeWithZone
|
||||||
|
|
|
@ -215,6 +215,95 @@ class TimeZoneTest < ActiveSupport::TestCase
|
||||||
assert_equal secs, twz.to_f
|
assert_equal secs, twz.to_f
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_iso8601
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("1999-12-31T19:00:00")
|
||||||
|
assert_equal Time.utc(1999, 12, 31, 19), twz.time
|
||||||
|
assert_equal Time.utc(2000), twz.utc
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_with_fractional_seconds
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("1999-12-31T19:00:00.750")
|
||||||
|
assert_equal 750000, twz.time.usec
|
||||||
|
assert_equal Time.utc(1999, 12, 31, 19, 0, 0 + Rational(3, 4)), twz.time
|
||||||
|
assert_equal Time.utc(2000, 1, 1, 0, 0, 0 + Rational(3, 4)), twz.utc
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_with_zone
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("1999-12-31T14:00:00-10:00")
|
||||||
|
assert_equal Time.utc(1999, 12, 31, 19), twz.time
|
||||||
|
assert_equal Time.utc(2000), twz.utc
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_with_invalid_string
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
|
||||||
|
exception = assert_raises(ArgumentError) do
|
||||||
|
zone.iso8601("foobar")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "invalid date", exception.message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_with_missing_time_components
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("1999-12-31")
|
||||||
|
assert_equal Time.utc(1999, 12, 31, 0, 0, 0), twz.time
|
||||||
|
assert_equal Time.utc(1999, 12, 31, 5, 0, 0), twz.utc
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_with_old_date
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("1883-12-31T19:00:00")
|
||||||
|
assert_equal [0, 0, 19, 31, 12, 1883], twz.to_a[0, 6]
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_far_future_date_with_time_zone_offset_in_string
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("2050-12-31T19:00:00-10:00") # i.e., 2050-01-01 05:00:00 UTC
|
||||||
|
assert_equal [0, 0, 0, 1, 1, 2051], twz.to_a[0, 6]
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_should_not_black_out_system_timezone_dst_jump
|
||||||
|
with_env_tz("EET") do
|
||||||
|
zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("2012-03-25T03:29:00")
|
||||||
|
assert_equal [0, 29, 3, 25, 3, 2012], twz.to_a[0, 6]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_should_black_out_app_timezone_dst_jump
|
||||||
|
with_env_tz("EET") do
|
||||||
|
zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("2012-03-11T02:29:00")
|
||||||
|
assert_equal [0, 29, 3, 11, 3, 2012], twz.to_a[0, 6]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_doesnt_use_local_dst
|
||||||
|
with_env_tz "US/Eastern" do
|
||||||
|
zone = ActiveSupport::TimeZone["UTC"]
|
||||||
|
twz = zone.iso8601("2013-03-10T02:00:00")
|
||||||
|
assert_equal Time.utc(2013, 3, 10, 2, 0, 0), twz.time
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_iso8601_handles_dst_jump
|
||||||
|
with_env_tz "US/Eastern" do
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("2013-03-10T02:00:00")
|
||||||
|
assert_equal Time.utc(2013, 3, 10, 3, 0, 0), twz.time
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_parse
|
def test_parse
|
||||||
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
twz = zone.parse("1999-12-31 19:00:00")
|
twz = zone.parse("1999-12-31 19:00:00")
|
||||||
|
@ -314,6 +403,99 @@ class TimeZoneTest < ActiveSupport::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_rfc3339
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.rfc3339("1999-12-31T14:00:00-10:00")
|
||||||
|
assert_equal Time.utc(1999, 12, 31, 19), twz.time
|
||||||
|
assert_equal Time.utc(2000), twz.utc
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_with_fractional_seconds
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("1999-12-31T14:00:00.750-10:00")
|
||||||
|
assert_equal 750000, twz.time.usec
|
||||||
|
assert_equal Time.utc(1999, 12, 31, 19, 0, 0 + Rational(3, 4)), twz.time
|
||||||
|
assert_equal Time.utc(2000, 1, 1, 0, 0, 0 + Rational(3, 4)), twz.utc
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_with_missing_time
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
|
||||||
|
exception = assert_raises(ArgumentError) do
|
||||||
|
zone.rfc3339("1999-12-31")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "invalid date", exception.message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_with_missing_offset
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
|
||||||
|
exception = assert_raises(ArgumentError) do
|
||||||
|
zone.rfc3339("1999-12-31T19:00:00")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "invalid date", exception.message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_with_invalid_string
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
|
||||||
|
exception = assert_raises(ArgumentError) do
|
||||||
|
zone.rfc3339("foobar")
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal "invalid date", exception.message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_with_old_date
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.rfc3339("1883-12-31T19:00:00-05:00")
|
||||||
|
assert_equal [0, 0, 19, 31, 12, 1883], twz.to_a[0, 6]
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_far_future_date_with_time_zone_offset_in_string
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.rfc3339("2050-12-31T19:00:00-10:00") # i.e., 2050-01-01 05:00:00 UTC
|
||||||
|
assert_equal [0, 0, 0, 1, 1, 2051], twz.to_a[0, 6]
|
||||||
|
assert_equal zone, twz.time_zone
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_should_not_black_out_system_timezone_dst_jump
|
||||||
|
with_env_tz("EET") do
|
||||||
|
zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"]
|
||||||
|
twz = zone.rfc3339("2012-03-25T03:29:00-07:00")
|
||||||
|
assert_equal [0, 29, 3, 25, 3, 2012], twz.to_a[0, 6]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_should_black_out_app_timezone_dst_jump
|
||||||
|
with_env_tz("EET") do
|
||||||
|
zone = ActiveSupport::TimeZone["Pacific Time (US & Canada)"]
|
||||||
|
twz = zone.rfc3339("2012-03-11T02:29:00-08:00")
|
||||||
|
assert_equal [0, 29, 3, 11, 3, 2012], twz.to_a[0, 6]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_doesnt_use_local_dst
|
||||||
|
with_env_tz "US/Eastern" do
|
||||||
|
zone = ActiveSupport::TimeZone["UTC"]
|
||||||
|
twz = zone.rfc3339("2013-03-10T02:00:00Z")
|
||||||
|
assert_equal Time.utc(2013, 3, 10, 2, 0, 0), twz.time
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rfc3339_handles_dst_jump
|
||||||
|
with_env_tz "US/Eastern" do
|
||||||
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
|
twz = zone.iso8601("2013-03-10T02:00:00-05:00")
|
||||||
|
assert_equal Time.utc(2013, 3, 10, 3, 0, 0), twz.time
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def test_strptime
|
def test_strptime
|
||||||
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"]
|
||||||
twz = zone.strptime("1999-12-31 12:00:00", "%Y-%m-%d %H:%M:%S")
|
twz = zone.strptime("1999-12-31 12:00:00", "%Y-%m-%d %H:%M:%S")
|
||||||
|
|
Loading…
Reference in a new issue