aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Daer <jeremydaer@gmail.com>2016-04-17 23:26:22 -0700
committerJeremy Daer <jeremydaer@gmail.com>2016-04-17 23:42:42 -0700
commit7254517f1efe896c53330d4ac0c4a48cd6559614 (patch)
tree43d32f68150aad890ee23bf73c76236a9531747e
parentcdce6131500820c9fd88709c46d84e57a9fd3f90 (diff)
parent1bf9fe75a6473cb7501cae544cab772713e68cef (diff)
downloadrails-7254517f1efe896c53330d4ac0c4a48cd6559614.tar.gz
rails-7254517f1efe896c53330d4ac0c4a48cd6559614.tar.bz2
rails-7254517f1efe896c53330d4ac0c4a48cd6559614.zip
Merge pull request #22806 from Envek/solid_durations
Introduce weeks and hours periods to Duration. Change 1.week to create a 1 week duration instead of 7 days and 1.hour to create a 1 hour duration instead of 3600 seconds.
-rw-r--r--activesupport/CHANGELOG.md20
-rw-r--r--activesupport/lib/active_support/core_ext/numeric/time.rb16
-rw-r--r--activesupport/lib/active_support/duration.rb4
-rw-r--r--activesupport/test/core_ext/duration_test.rb5
4 files changed, 34 insertions, 11 deletions
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 5729a98b99..b2ab5ffcbe 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,23 @@
+* `ActiveSupport::Duration` supports weeks and hours.
+
+ [1.hour.inspect, 1.hour.value, 1.hour.parts]
+ # => ["3600 seconds", 3600, [[:seconds, 3600]]] # Before
+ # => ["1 hour", 3600, [[:hours, 1]]] # After
+
+ [1.week.inspect, 1.week.value, 1.week.parts]
+ # => ["7 days", 604800, [[:days, 7]]] # Before
+ # => ["1 week", 604800, [[:weeks, 1]]] # After
+
+ This brings us into closer conformance with ISO8601 and relieves some
+ astonishment about getting `1.hour.inspect # => 3600 seconds`.
+
+ Compatibility: The duration's `value` remains the same, so apps using
+ durations are oblivious to the new time periods. Apps, libraries, and
+ plugins that work with the internal `parts` hash will need to broaden
+ their time period handling to cover hours & weeks.
+
+ *Andrey Novikov*
+
* Fix behavior of JSON encoding for `Exception`.
*namusyaka*
diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb
index 6c4a975495..c6ece22f8d 100644
--- a/activesupport/lib/active_support/core_ext/numeric/time.rb
+++ b/activesupport/lib/active_support/core_ext/numeric/time.rb
@@ -25,17 +25,17 @@ class Numeric
# Returns a Duration instance matching the number of minutes provided.
#
- # 2.minutes # => 120 seconds
+ # 2.minutes # => 2 minutes
def minutes
- ActiveSupport::Duration.new(self * 60, [[:seconds, self * 60]])
+ ActiveSupport::Duration.new(self * 60, [[:minutes, self]])
end
alias :minute :minutes
# Returns a Duration instance matching the number of hours provided.
#
- # 2.hours # => 7_200 seconds
+ # 2.hours # => 2 hours
def hours
- ActiveSupport::Duration.new(self * 3600, [[:seconds, self * 3600]])
+ ActiveSupport::Duration.new(self * 3600, [[:hours, self]])
end
alias :hour :hours
@@ -49,17 +49,17 @@ class Numeric
# Returns a Duration instance matching the number of weeks provided.
#
- # 2.weeks # => 14 days
+ # 2.weeks # => 2 weeks
def weeks
- ActiveSupport::Duration.new(self * 7.days, [[:days, self * 7]])
+ ActiveSupport::Duration.new(self * 7.days, [[:weeks, self]])
end
alias :week :weeks
# Returns a Duration instance matching the number of fortnights provided.
#
- # 2.fortnights # => 28 days
+ # 2.fortnights # => 4 weeks
def fortnights
- ActiveSupport::Duration.new(self * 2.weeks, [[:days, self * 14]])
+ ActiveSupport::Duration.new(self * 2.weeks, [[:weeks, self * 2]])
end
alias :fortnight :fortnights
diff --git a/activesupport/lib/active_support/duration.rb b/activesupport/lib/active_support/duration.rb
index c63b61e97a..f67a42bcb1 100644
--- a/activesupport/lib/active_support/duration.rb
+++ b/activesupport/lib/active_support/duration.rb
@@ -117,7 +117,7 @@ module ActiveSupport
def inspect #:nodoc:
parts.
reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
- sort_by {|unit, _ | [:years, :months, :days, :minutes, :seconds].index(unit)}.
+ sort_by {|unit, _ | [:years, :months, :weeks, :days, :hours, :minutes, :seconds].index(unit)}.
map {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}.
to_sentence(locale: ::I18n.default_locale)
end
@@ -139,6 +139,8 @@ module ActiveSupport
if t.acts_like?(:time) || t.acts_like?(:date)
if type == :seconds
t.since(sign * number)
+ elsif [:hours, :minutes].include?(type)
+ t.in_time_zone.advance(type => sign * number)
else
t.advance(type => sign * number)
end
diff --git a/activesupport/test/core_ext/duration_test.rb b/activesupport/test/core_ext/duration_test.rb
index 9e97acaffb..a6a43048db 100644
--- a/activesupport/test/core_ext/duration_test.rb
+++ b/activesupport/test/core_ext/duration_test.rb
@@ -66,8 +66,9 @@ class DurationTest < ActiveSupport::TestCase
assert_equal '10 years, 2 months, and 1 day', (10.years + 2.months + 1.day).inspect
assert_equal '10 years, 2 months, and 1 day', (10.years + 1.month + 1.day + 1.month).inspect
assert_equal '10 years, 2 months, and 1 day', (1.day + 10.years + 2.months).inspect
- assert_equal '7 days', 1.week.inspect
- assert_equal '14 days', 1.fortnight.inspect
+ assert_equal '7 days', 7.days.inspect
+ assert_equal '1 week', 1.week.inspect
+ assert_equal '2 weeks', 1.fortnight.inspect
end
def test_inspect_locale