提交 333ff24b 编写于 作者: T T.J. Schuck

Refactor Date/Time next_occurring and prev_occurring

These methods were originally added in https://github.com/rails/rails/pull/26600

This includes a couple of refactors to make these methods behave more similarly to other Date/Time extensions added by Active Support:

1. Use `advance` instead of `since` and `ago` to time-travel — this is particularly important to keep the returned instance’s class matching `self`.  Before this change:

    today = Date.today                     # => Tue, 28 Nov 2017
    today.class                            # => Date
    today.next_occurring(:wednesday)       # => Wed, 29 Nov 2017 00:00:00 UTC +00:00
    today.next_occurring(:wednesday).class # => ActiveSupport::TimeWithZone

  After this change, a Date (or Time, or DateTime) instance is properly returned (just like is shown in the new docs).  This is generally how everything else in DateAndTime::Calculations works.

2. Move the tests from the DateTime tests to the DateAndTimeBehavior tests.  The latter location is mixed in to the core_ext tests for _all_ of Date, Time, and DateTime to test the behavior across all of the classes.  The previous location is for testing core_ext functionality added specifically just to DateTime.

3. Better docs!
上级 86335671
......@@ -330,20 +330,28 @@ def all_year
beginning_of_year..end_of_year
end
# Returns specific next occurring day of week
# Returns a new date/time representing the next occurrence of the specified day of week.
#
# today = Date.today # => Thu, 14 Dec 2017
# today.next_occurring(:monday) # => Mon, 18 Dec 2017
# today.next_occurring(:thursday) # => Thu, 21 Dec 2017
def next_occurring(day_of_week)
current_day_number = wday != 0 ? wday - 1 : 6
from_now = DAYS_INTO_WEEK.fetch(day_of_week) - current_day_number
from_now += 7 unless from_now > 0
since(from_now.days)
advance(days: from_now)
end
# Returns specific previous occurring day of week
# Returns a new date/time representing the previous occurrence of the specified day of week.
#
# today = Date.today # => Thu, 14 Dec 2017
# today.prev_occurring(:monday) # => Mon, 11 Dec 2017
# today.prev_occurring(:thursday) # => Thu, 07 Dec 2017
def prev_occurring(day_of_week)
current_day_number = wday != 0 ? wday - 1 : 6
ago = current_day_number - DAYS_INTO_WEEK.fetch(day_of_week)
ago += 7 unless ago > 0
ago(ago.days)
advance(days: -ago)
end
private
......
......@@ -328,6 +328,26 @@ def test_end_of_year
assert_equal date_time_init(2007, 12, 31, 23, 59, 59, Rational(999999999, 1000)), date_time_init(2007, 12, 31, 10, 10, 10).end_of_year
end
def test_next_occurring
assert_equal date_time_init(2017, 12, 18, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:monday)
assert_equal date_time_init(2017, 12, 19, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:tuesday)
assert_equal date_time_init(2017, 12, 20, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:wednesday)
assert_equal date_time_init(2017, 12, 21, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:thursday)
assert_equal date_time_init(2017, 12, 15, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:friday)
assert_equal date_time_init(2017, 12, 16, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:saturday)
assert_equal date_time_init(2017, 12, 17, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).next_occurring(:sunday)
end
def test_prev_occurring
assert_equal date_time_init(2017, 12, 11, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:monday)
assert_equal date_time_init(2017, 12, 12, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:tuesday)
assert_equal date_time_init(2017, 12, 13, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:wednesday)
assert_equal date_time_init(2017, 12, 7, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:thursday)
assert_equal date_time_init(2017, 12, 8, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:friday)
assert_equal date_time_init(2017, 12, 9, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:saturday)
assert_equal date_time_init(2017, 12, 10, 3, 14, 15), date_time_init(2017, 12, 14, 3, 14, 15).prev_occurring(:sunday)
end
def test_monday_with_default_beginning_of_week_set
with_bw_default(:saturday) do
assert_equal date_time_init(2012, 9, 17, 0, 0, 0), date_time_init(2012, 9, 18, 0, 0, 0).monday
......
......@@ -30,28 +30,6 @@ def test_to_s
end
end
def test_next_occur
datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday
assert_equal datetime.next_occurring(:monday), datetime.since(2.days)
assert_equal datetime.next_occurring(:tuesday), datetime.since(3.days)
assert_equal datetime.next_occurring(:wednesday), datetime.since(4.days)
assert_equal datetime.next_occurring(:thursday), datetime.since(5.days)
assert_equal datetime.next_occurring(:friday), datetime.since(6.days)
assert_equal datetime.next_occurring(:saturday), datetime.since(1.week)
assert_equal datetime.next_occurring(:sunday), datetime.since(1.day)
end
def test_prev_occur
datetime = DateTime.new(2016, 9, 24, 0, 0) # saturday
assert_equal datetime.prev_occurring(:monday), datetime.ago(5.days)
assert_equal datetime.prev_occurring(:tuesday), datetime.ago(4.days)
assert_equal datetime.prev_occurring(:wednesday), datetime.ago(3.days)
assert_equal datetime.prev_occurring(:thursday), datetime.ago(2.days)
assert_equal datetime.prev_occurring(:friday), datetime.ago(1.day)
assert_equal datetime.prev_occurring(:saturday), datetime.ago(1.week)
assert_equal datetime.prev_occurring(:sunday), datetime.ago(6.days)
end
def test_readable_inspect
datetime = DateTime.new(2005, 2, 21, 14, 30, 0)
assert_equal "Mon, 21 Feb 2005 14:30:00 +0000", datetime.readable_inspect
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册