From bc1bcddede0c300e9c88f76a66a152814b734981 Mon Sep 17 00:00:00 2001 From: Rob Zolkos & Xavier Noria Date: Sat, 16 Oct 2010 02:22:12 +0200 Subject: implements weeks_ago and prev_week for Date/DateTime/Time [#5122 state:committed] --- .../lib/active_support/core_ext/date/calculations.rb | 16 ++++++++++++++-- .../lib/active_support/core_ext/time/calculations.rb | 12 +++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) (limited to 'activesupport/lib') diff --git a/activesupport/lib/active_support/core_ext/date/calculations.rb b/activesupport/lib/active_support/core_ext/date/calculations.rb index 1856b4dd8b..f34185f22c 100644 --- a/activesupport/lib/active_support/core_ext/date/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date/calculations.rb @@ -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 diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index d430751623..fa052fa86b 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -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) -- cgit v1.2.3