Add same_time option to #prev_week and #next_week for Date, Time, and DateTime

This commit is contained in:
George Claghorn 2015-01-05 23:06:45 -05:00
parent adf5fc3b3c
commit b6d0d0d106
3 changed files with 42 additions and 17 deletions

@ -1,3 +1,8 @@
* Add `same_time` option to `#next_week` and `#prev_week` for `Date`, `Time`,
and `DateTime`.
*George Claghorn*
* Add `#on_weekend?`, `#next_weekday`, `#prev_weekday` methods to `Date`,
`Time`, and `DateTime`.

@ -117,15 +117,16 @@ def beginning_of_year
# Returns a new date/time representing the given day in the next week.
# The +given_day_in_next_week+ defaults to the beginning of the week
# which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+
# when set. +DateTime+ objects have their time set to 0:00.
def next_week(given_day_in_next_week = Date.beginning_of_week)
first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
# when set. +DateTime+ objects have their time set to 0:00 unless +same_time+ is true.
def next_week(given_day_in_next_week = Date.beginning_of_week, same_time: false)
result = first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week)))
same_time ? copy_time_to(result) : result
end
# Returns a new date/time representing the next weekday.
def next_weekday
if tomorrow.on_weekend?
next_week(:monday).change(hour: hour, min: min, sec: sec, usec: try(:usec))
next_week(:monday, same_time: true)
else
tomorrow
end
@ -149,16 +150,17 @@ def next_year
# Returns a new date/time representing the given day in the previous week.
# Week is assumed to start on +start_day+, default is
# +Date.beginning_of_week+ or +config.beginning_of_week+ when set.
# DateTime objects have their time set to 0:00.
def prev_week(start_day = Date.beginning_of_week)
first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
# DateTime objects have their time set to 0:00 unless +same_time+ is true.
def prev_week(start_day = Date.beginning_of_week, same_time: false)
result = first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day)))
same_time ? copy_time_to(result) : result
end
alias_method :last_week, :prev_week
# Returns a new date/time representing the previous weekday.
def prev_weekday
if yesterday.on_weekend?
beginning_of_week(:friday).change(hour: hour, min: min, sec: sec, usec: try(:usec))
copy_time_to(beginning_of_week(:friday))
else
yesterday
end
@ -260,17 +262,20 @@ def all_year
end
private
def first_hour(date_or_time)
date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
end
def first_hour(date_or_time)
date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time
end
def last_hour(date_or_time)
date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time
end
def last_hour(date_or_time)
date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time
end
def days_span(day)
(DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
end
def days_span(day)
(DAYS_INTO_WEEK[day] - DAYS_INTO_WEEK[Date.beginning_of_week]) % 7
end
def copy_time_to(other)
other.change(hour: hour, min: min, sec: sec, usec: try(:usec))
end
end
end

@ -115,6 +115,13 @@ def test_next_week_with_default_beginning_of_week_set
end
end
def test_next_week_at_same_time
assert_equal date_time_init(2005,2,28,15,15,10), date_time_init(2005,2,22,15,15,10).next_week(:monday, same_time: true)
assert_equal date_time_init(2005,3,4,15,15,10), date_time_init(2005,2,22,15,15,10).next_week(:friday, same_time: true)
assert_equal date_time_init(2006,10,30,0,0,0), date_time_init(2006,10,23,0,0,0).next_week(:monday, same_time: true)
assert_equal date_time_init(2006,11,1,0,0,0), date_time_init(2006,10,23,0,0,0).next_week(:wednesday, same_time: true)
end
def test_next_weekday_on_wednesday
assert_equal date_time_init(2015,1,8,0,0,0), date_time_init(2015,1,7,0,0,0).next_weekday
assert_equal date_time_init(2015,1,8,15,15,10), date_time_init(2015,1,7,15,15,10).next_weekday
@ -159,6 +166,14 @@ def test_prev_week_with_default_beginning_of_week
end
end
def test_prev_week_at_same_time
assert_equal date_time_init(2005,2,21,15,15,10), date_time_init(2005,3,1,15,15,10).prev_week(:monday, same_time: true)
assert_equal date_time_init(2005,2,22,15,15,10), date_time_init(2005,3,1,15,15,10).prev_week(:tuesday, same_time: true)
assert_equal date_time_init(2005,2,25,15,15,10), date_time_init(2005,3,1,15,15,10).prev_week(:friday, same_time: true)
assert_equal date_time_init(2006,10,30,0,0,0), date_time_init(2006,11,6,0,0,0).prev_week(:monday, same_time: true)
assert_equal date_time_init(2006,11,15,0,0,0), date_time_init(2006,11,23,0,0,0).prev_week(:wednesday, same_time: true)
end
def test_prev_weekday_on_wednesday
assert_equal date_time_init(2015,1,6,0,0,0), date_time_init(2015,1,7,0,0,0).prev_weekday
assert_equal date_time_init(2015,1,6,15,15,10), date_time_init(2015,1,7,15,15,10).prev_weekday