aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorAndrew White <andrew.white@unboxed.co>2017-03-03 14:58:35 +0000
committerAndrew White <andrew.white@unboxed.co>2017-03-03 21:53:12 +0000
commit4974b1a483774f67fc2ac6595c3f492bad608605 (patch)
tree00e2b0f68e042c56b76524664245c84fb28b5c29 /activesupport/lib
parentd3e7d91050da858bd5ec6a061b96466bd9ac85ef (diff)
downloadrails-4974b1a483774f67fc2ac6595c3f492bad608605.tar.gz
rails-4974b1a483774f67fc2ac6595c3f492bad608605.tar.bz2
rails-4974b1a483774f67fc2ac6595c3f492bad608605.zip
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
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/values/time_zone.rb35
1 files changed, 35 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/values/time_zone.rb b/activesupport/lib/active_support/values/time_zone.rb
index 09cb9cbbe1..1dedd6d06e 100644
--- a/activesupport/lib/active_support/values/time_zone.rb
+++ b/activesupport/lib/active_support/values/time_zone.rb
@@ -340,6 +340,41 @@ module ActiveSupport
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
# of +self+ from parsed string.
#
# Time.zone = 'Hawaii' # => "Hawaii"