mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
implements weeks_ago and prev_week for Date/DateTime/Time [#5122 state:committed]
This commit is contained in:
parent
4bfe30ca2f
commit
bc1bcddede
7 changed files with 100 additions and 5 deletions
|
@ -1,5 +1,7 @@
|
|||
*Rails 3.1.0 (unreleased)*
|
||||
|
||||
* Added weeks_ago and prev_week to Date/DateTime/Time. [Rob Zolkos, fxn]
|
||||
|
||||
* Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ require 'active_support/core_ext/date/zones'
|
|||
require 'active_support/core_ext/time/zones'
|
||||
|
||||
class Date
|
||||
DAYS_INTO_WEEK = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6 }
|
||||
|
||||
if RUBY_VERSION < '1.9'
|
||||
undef :>>
|
||||
|
||||
|
@ -127,6 +129,11 @@ class Date
|
|||
)
|
||||
end
|
||||
|
||||
# Returns a new Date/DateTime representing the time a number of specified weeks ago.
|
||||
def weeks_ago(weeks)
|
||||
advance(:weeks => -weeks)
|
||||
end
|
||||
|
||||
# Returns a new Date/DateTime representing the time a number of specified months ago.
|
||||
def months_ago(months)
|
||||
advance(:months => -months)
|
||||
|
@ -185,10 +192,15 @@ class Date
|
|||
alias :sunday :end_of_week
|
||||
alias :at_end_of_week :end_of_week
|
||||
|
||||
# Returns a new Date/DateTime representing the start of the given day in the previous week (default is Monday).
|
||||
def prev_week(day = :monday)
|
||||
result = (self - 7).beginning_of_week + DAYS_INTO_WEEK[day]
|
||||
self.acts_like?(:time) ? result.change(:hour => 0) : result
|
||||
end
|
||||
|
||||
# Returns a new Date/DateTime representing the start of the given day in next week (default is Monday).
|
||||
def next_week(day = :monday)
|
||||
days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
|
||||
result = (self + 7).beginning_of_week + days_into_week[day]
|
||||
result = (self + 7).beginning_of_week + DAYS_INTO_WEEK[day]
|
||||
self.acts_like?(:time) ? result.change(:hour => 0) : result
|
||||
end
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class Time
|
|||
|
||||
# Returns a new Time if requested year can be accommodated by Ruby's Time class
|
||||
# (i.e., if year is within either 1970..2038 or 1902..2038, depending on system architecture);
|
||||
# otherwise returns a DateTime
|
||||
# otherwise returns a DateTime.
|
||||
def time_with_datetime_fallback(utc_or_local, year, month=1, day=1, hour=0, min=0, sec=0, usec=0)
|
||||
time = ::Time.send(utc_or_local, year, month, day, hour, min, sec, usec)
|
||||
# This check is needed because Time.utc(y) returns a time object in the 2000s for 0 <= y <= 138.
|
||||
|
@ -117,6 +117,11 @@ class Time
|
|||
end
|
||||
alias :in :since
|
||||
|
||||
# Returns a new Time representing the time a number of specified weeks ago.
|
||||
def weeks_ago(weeks)
|
||||
advance(:weeks => -weeks)
|
||||
end
|
||||
|
||||
# Returns a new Time representing the time a number of specified months ago
|
||||
def months_ago(months)
|
||||
advance(:months => -months)
|
||||
|
@ -172,6 +177,11 @@ class Time
|
|||
end
|
||||
alias :at_end_of_week :end_of_week
|
||||
|
||||
# Returns a new Time representing the start of the given day in the previous week (default is Monday).
|
||||
def prev_week(day = :monday)
|
||||
ago(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
|
||||
end
|
||||
|
||||
# Returns a new Time representing the start of the given day in next week (default is Monday).
|
||||
def next_week(day = :monday)
|
||||
since(1.week).beginning_of_week.since(DAYS_INTO_WEEK[day].day).change(:hour => 0)
|
||||
|
|
|
@ -110,6 +110,14 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
|
|||
assert_equal Date.new(2005,1,1).to_s, Date.new(2005,2,22).beginning_of_year.to_s
|
||||
end
|
||||
|
||||
def test_weeks_ago
|
||||
assert_equal Date.new(2005,5,10), Date.new(2005,5,17).weeks_ago(1)
|
||||
assert_equal Date.new(2005,5,10), Date.new(2005,5,24).weeks_ago(2)
|
||||
assert_equal Date.new(2005,5,10), Date.new(2005,5,31).weeks_ago(3)
|
||||
assert_equal Date.new(2005,5,10), Date.new(2005,6,7).weeks_ago(4)
|
||||
assert_equal Date.new(2006,12,31), Date.new(2007,2,4).weeks_ago(5)
|
||||
end
|
||||
|
||||
def test_months_ago
|
||||
assert_equal Date.new(2005,5,5), Date.new(2005,6,5).months_ago(1)
|
||||
assert_equal Date.new(2004,11,5), Date.new(2005,6,5).months_ago(7)
|
||||
|
@ -219,6 +227,14 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_prev_week
|
||||
assert_equal Date.new(2005,5,9), Date.new(2005,5,17).prev_week
|
||||
assert_equal Date.new(2006,12,25), Date.new(2007,1,7).prev_week
|
||||
assert_equal Date.new(2010,2,12), Date.new(2010,2,19).prev_week(:friday)
|
||||
assert_equal Date.new(2010,2,13), Date.new(2010,2,19).prev_week(:saturday)
|
||||
assert_equal Date.new(2010,2,27), Date.new(2010,3,4).prev_week(:saturday)
|
||||
end
|
||||
|
||||
def test_next_week
|
||||
assert_equal Date.new(2005,2,28), Date.new(2005,2,22).next_week
|
||||
assert_equal Date.new(2005,3,4), Date.new(2005,2,22).next_week(:friday)
|
||||
|
|
|
@ -92,6 +92,14 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase
|
|||
assert_equal DateTime.civil(2005,1,1,0,0,0), DateTime.civil(2005,2,22,10,10,10).beginning_of_year
|
||||
end
|
||||
|
||||
def test_weeks_ago
|
||||
assert_equal DateTime.civil(2005,5,29,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(1)
|
||||
assert_equal DateTime.civil(2005,5,1,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(5)
|
||||
assert_equal DateTime.civil(2005,4,24,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(6)
|
||||
assert_equal DateTime.civil(2005,2,27,10), DateTime.civil(2005,6,5,10,0,0).weeks_ago(14)
|
||||
assert_equal DateTime.civil(2004,12,25,10), DateTime.civil(2005,1,1,10,0,0).weeks_ago(1)
|
||||
end
|
||||
|
||||
def test_months_ago
|
||||
assert_equal DateTime.civil(2005,5,5,10), DateTime.civil(2005,6,5,10,0,0).months_ago(1)
|
||||
assert_equal DateTime.civil(2004,11,5,10), DateTime.civil(2005,6,5,10,0,0).months_ago(7)
|
||||
|
@ -196,6 +204,14 @@ class DateTimeExtCalculationsTest < Test::Unit::TestCase
|
|||
assert_equal DateTime.civil(2010, 3, 29), DateTime.civil(2010, 2, 28, 22, 58, 59).advance(:months => 1, :hours => 1, :minutes => 1, :seconds => 1)
|
||||
end
|
||||
|
||||
def test_prev_week
|
||||
assert_equal DateTime.civil(2005,2,21), DateTime.civil(2005,3,1,15,15,10).prev_week
|
||||
assert_equal DateTime.civil(2005,2,22), DateTime.civil(2005,3,1,15,15,10).prev_week(:tuesday)
|
||||
assert_equal DateTime.civil(2005,2,25), DateTime.civil(2005,3,1,15,15,10).prev_week(:friday)
|
||||
assert_equal DateTime.civil(2006,10,30), DateTime.civil(2006,11,6,0,0,0).prev_week
|
||||
assert_equal DateTime.civil(2006,11,15), DateTime.civil(2006,11,23,0,0,0).prev_week(:wednesday)
|
||||
end
|
||||
|
||||
def test_next_week
|
||||
assert_equal DateTime.civil(2005,2,28), DateTime.civil(2005,2,22,15,15,10).next_week
|
||||
assert_equal DateTime.civil(2005,3,4), DateTime.civil(2005,2,22,15,15,10).next_week(:friday)
|
||||
|
|
|
@ -130,6 +130,14 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
|
|||
assert_equal Time.local(2005,1,1,0,0,0), Time.local(2005,2,22,10,10,10).beginning_of_year
|
||||
end
|
||||
|
||||
def test_weeks_ago
|
||||
assert_equal Time.local(2005,5,29,10), Time.local(2005,6,5,10,0,0).weeks_ago(1)
|
||||
assert_equal Time.local(2005,5,1,10), Time.local(2005,6,5,10,0,0).weeks_ago(5)
|
||||
assert_equal Time.local(2005,4,24,10), Time.local(2005,6,5,10,0,0).weeks_ago(6)
|
||||
assert_equal Time.local(2005,2,27,10), Time.local(2005,6,5,10,0,0).weeks_ago(14)
|
||||
assert_equal Time.local(2004,12,25,10), Time.local(2005,1,1,10,0,0).weeks_ago(1)
|
||||
end
|
||||
|
||||
def test_months_ago
|
||||
assert_equal Time.local(2005,5,5,10), Time.local(2005,6,5,10,0,0).months_ago(1)
|
||||
assert_equal Time.local(2004,11,5,10), Time.local(2005,6,5,10,0,0).months_ago(7)
|
||||
|
@ -463,6 +471,16 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase
|
|||
assert_equal Time.utc(2013,10,17,20,22,19), Time.utc(2005,2,28,15,15,10).advance(:years => 7, :months => 19, :weeks => 2, :days => 5, :hours => 5, :minutes => 7, :seconds => 9)
|
||||
end
|
||||
|
||||
def test_prev_week
|
||||
with_env_tz 'US/Eastern' do
|
||||
assert_equal Time.local(2005,2,21), Time.local(2005,3,1,15,15,10).prev_week
|
||||
assert_equal Time.local(2005,2,22), Time.local(2005,3,1,15,15,10).prev_week(:tuesday)
|
||||
assert_equal Time.local(2005,2,25), Time.local(2005,3,1,15,15,10).prev_week(:friday)
|
||||
assert_equal Time.local(2006,10,30), Time.local(2006,11,6,0,0,0).prev_week
|
||||
assert_equal Time.local(2006,11,15), Time.local(2006,11,23,0,0,0).prev_week(:wednesday)
|
||||
end
|
||||
end
|
||||
|
||||
def test_next_week
|
||||
with_env_tz 'US/Eastern' do
|
||||
assert_equal Time.local(2005,2,28), Time.local(2005,2,22,15,15,10).next_week
|
||||
|
|
|
@ -2859,9 +2859,9 @@ d.end_of_week # => Sun, 09 May 2010
|
|||
|
||||
+beginning_of_week+ is aliased to +monday+ and +at_beginning_of_week+. +end_of_week+ is aliased to +sunday+ and +at_end_of_week+.
|
||||
|
||||
h6. +next_week+
|
||||
h6. +prev_week+, +next_week+
|
||||
|
||||
+next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day in the next week:
|
||||
The method +next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day:
|
||||
|
||||
<ruby>
|
||||
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
|
||||
|
@ -2869,6 +2869,14 @@ d.next_week # => Mon, 10 May 2010
|
|||
d.next_week(:saturday) # => Sat, 15 May 2010
|
||||
</ruby>
|
||||
|
||||
The method +prev_week+ is analogous:
|
||||
|
||||
<ruby>
|
||||
d.prev_week # => Mon, 26 Apr 2010
|
||||
d.prev_week(:saturday) # => Sat, 01 May 2010
|
||||
d.prev_week(:friday) # => Fri, 30 Apr 2010
|
||||
</ruby>
|
||||
|
||||
h6. +beginning_of_month+, +end_of_month+
|
||||
|
||||
The methods +beginning_of_month+ and +end_of_month+ return the dates for the beginning and end of the month:
|
||||
|
@ -2946,6 +2954,15 @@ Date.new(2010, 4, 30).months_ago(2) # => Sun, 28 Feb 2010
|
|||
Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
|
||||
</ruby>
|
||||
|
||||
h6. +weeks_ago+
|
||||
|
||||
The method +weeks_ago+ works analogously for weeks:
|
||||
|
||||
<ruby>
|
||||
Date.new(2010, 5, 24).weeks_ago(1) # => Mon, 17 May 2010
|
||||
Date.new(2010, 5, 24).weeks_ago(2) # => Mon, 10 May 2010
|
||||
</ruby>
|
||||
|
||||
h6. +advance+
|
||||
|
||||
The most generic way to jump to other days is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, and returns a date advanced as much as the present keys indicate:
|
||||
|
@ -3067,6 +3084,8 @@ yesterday
|
|||
tomorrow
|
||||
beginning_of_week (monday, at_beginning_of_week)
|
||||
end_on_week (at_end_of_week)
|
||||
weeks_ago
|
||||
prev_week
|
||||
next_week
|
||||
months_ago
|
||||
months_since
|
||||
|
@ -3239,6 +3258,8 @@ beginning_of_day (midnight, at_midnight, at_beginning_of_day)
|
|||
end_of_day
|
||||
beginning_of_week (monday, at_beginning_of_week)
|
||||
end_on_week (at_end_of_week)
|
||||
weeks_ago
|
||||
prev_week
|
||||
next_week
|
||||
months_ago
|
||||
months_since
|
||||
|
|
Loading…
Reference in a new issue