aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/core_ext/time
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib/active_support/core_ext/time')
-rw-r--r--activesupport/lib/active_support/core_ext/time/acts_like.rb2
-rw-r--r--activesupport/lib/active_support/core_ext/time/calculations.rb61
-rw-r--r--activesupport/lib/active_support/core_ext/time/compatibility.rb13
-rw-r--r--activesupport/lib/active_support/core_ext/time/conversions.rb5
-rw-r--r--activesupport/lib/active_support/core_ext/time/zones.rb10
5 files changed, 71 insertions, 20 deletions
diff --git a/activesupport/lib/active_support/core_ext/time/acts_like.rb b/activesupport/lib/active_support/core_ext/time/acts_like.rb
index cf4b2539c5..8572b49639 100644
--- a/activesupport/lib/active_support/core_ext/time/acts_like.rb
+++ b/activesupport/lib/active_support/core_ext/time/acts_like.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/object/acts_like"
class Time
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb
index cbdcb86d6d..120768dec5 100644
--- a/activesupport/lib/active_support/core_ext/time/calculations.rb
+++ b/activesupport/lib/active_support/core_ext/time/calculations.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/duration"
require "active_support/core_ext/time/conversions"
require "active_support/time_with_zone"
@@ -53,6 +55,29 @@ class Time
end
alias_method :at_without_coercion, :at
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
# Returns the number of seconds since 00:00:00.
@@ -84,21 +109,22 @@ class Time
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
- # and minute is passed, then sec, usec and nsec is set to 0. The +options+
- # parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
- # <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
- # <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
+ # and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
+ # takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
+ # <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
+ # <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
#
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
def change(options)
- new_year = options.fetch(:year, year)
- new_month = options.fetch(:month, month)
- new_day = options.fetch(:day, day)
- new_hour = options.fetch(:hour, hour)
- new_min = options.fetch(:min, options[:hour] ? 0 : min)
- new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
+ new_year = options.fetch(:year, year)
+ new_month = options.fetch(:month, month)
+ new_day = options.fetch(:day, day)
+ new_hour = options.fetch(:hour, hour)
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
+ new_offset = options.fetch(:offset, nil)
if new_nsec = options[:nsec]
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
@@ -107,13 +133,18 @@ class Time
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
end
- if utc?
- ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
+ raise ArgumentError, "argument out of range" if new_usec >= 1000000
+
+ new_sec += Rational(new_usec, 1000000)
+
+ if new_offset
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
+ elsif utc?
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
elsif zone
- ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
else
- raise ArgumentError, "argument out of range" if new_usec >= 1000000
- ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
end
end
diff --git a/activesupport/lib/active_support/core_ext/time/compatibility.rb b/activesupport/lib/active_support/core_ext/time/compatibility.rb
index ca4b9574d5..495e4f307b 100644
--- a/activesupport/lib/active_support/core_ext/time/compatibility.rb
+++ b/activesupport/lib/active_support/core_ext/time/compatibility.rb
@@ -1,5 +1,16 @@
+# frozen_string_literal: true
+
require "active_support/core_ext/date_and_time/compatibility"
+require "active_support/core_ext/module/redefine_method"
class Time
- prepend DateAndTime::Compatibility
+ include DateAndTime::Compatibility
+
+ silence_redefinition_of_method :to_time
+
+ # Either return +self+ or the time in the local system timezone depending
+ # on the setting of +ActiveSupport.to_time_preserves_timezone+.
+ def to_time
+ preserve_timezone ? self : getlocal
+ end
end
diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb
index f2bbe55aa6..345cb2832c 100644
--- a/activesupport/lib/active_support/core_ext/time/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/time/conversions.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/inflector/methods"
require "active_support/values/time_zone"
@@ -64,4 +66,7 @@ class Time
def formatted_offset(colon = true, alternate_utc_string = nil)
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
end
+
+ # Aliased to +xmlschema+ for compatibility with +DateTime+
+ alias_method :rfc3339, :xmlschema
end
diff --git a/activesupport/lib/active_support/core_ext/time/zones.rb b/activesupport/lib/active_support/core_ext/time/zones.rb
index 87b5ad903a..a5588fd488 100644
--- a/activesupport/lib/active_support/core_ext/time/zones.rb
+++ b/activesupport/lib/active_support/core_ext/time/zones.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
require "active_support/time_with_zone"
require "active_support/core_ext/time/acts_like"
require "active_support/core_ext/date_and_time/zones"
@@ -53,10 +55,10 @@ class Time
# end
# end
#
- # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
- # objects that have already been created, e.g. any model timestamp
- # attributes that have been read before the block will remain in
- # the application's default timezone.
+ # NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
+ # objects that have already been created, e.g. any model timestamp
+ # attributes that have been read before the block will remain in
+ # the application's default timezone.
def use_zone(time_zone)
new_zone = find_zone!(time_zone)
begin