diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext/date_and_time')
-rw-r--r-- | activesupport/lib/active_support/core_ext/date_and_time/calculations.rb | 51 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/date_and_time/zones.rb | 41 |
2 files changed, 76 insertions, 16 deletions
diff --git a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb index 1f78b9eb5a..b85e49aca5 100644 --- a/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/date_and_time/calculations.rb @@ -78,7 +78,7 @@ module DateAndTime # Returns a new date/time at the start of the month. # DateTime objects will have a time set to 0:00. def beginning_of_month - first_hour{ change(:day => 1) } + first_hour(change(:day => 1)) end alias :at_beginning_of_month :beginning_of_month @@ -93,7 +93,7 @@ module DateAndTime # Returns a new date/time at the end of the quarter. # Example: 31st March, 30th June, 30th September. - # DateTIme objects will have a time set to 23:59:59. + # DateTime objects will have a time set to 23:59:59. def end_of_quarter last_quarter_month = [3, 6, 9, 12].detect { |m| m >= month } beginning_of_month.change(:month => last_quarter_month).end_of_month @@ -109,11 +109,11 @@ module DateAndTime alias :at_beginning_of_year :beginning_of_year # Returns a new date/time representing the given day in the next 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 next_week(start_day = Date.beginning_of_week) - first_hour{ weeks_since(1).beginning_of_week.days_since(days_span(start_day)) } + # 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))) end # Short-hand for months_since(1). @@ -136,7 +136,7 @@ module DateAndTime # +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)) } + first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day))) end alias_method :last_week, :prev_week @@ -188,7 +188,7 @@ module DateAndTime # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. # DateTime objects have their time set to 23:59:59. def end_of_week(start_day = Date.beginning_of_week) - last_hour{ days_since(6 - days_to_week_start(start_day)) } + last_hour(days_since(6 - days_to_week_start(start_day))) end alias :at_end_of_week :end_of_week @@ -202,7 +202,7 @@ module DateAndTime # DateTime objects will have a time set to 23:59:59. def end_of_month last_day = ::Time.days_in_month(month, year) - last_hour{ days_since(last_day - day) } + last_hour(days_since(last_day - day)) end alias :at_end_of_month :end_of_month @@ -213,16 +213,35 @@ module DateAndTime end alias :at_end_of_year :end_of_year + # Returns a Range representing the whole week of the current date/time. + # Week starts on start_day, default is <tt>Date.week_start</tt> or <tt>config.week_start</tt> when set. + def all_week(start_day = Date.beginning_of_week) + beginning_of_week(start_day)..end_of_week(start_day) + end + + # Returns a Range representing the whole month of the current date/time. + def all_month + beginning_of_month..end_of_month + end + + # Returns a Range representing the whole quarter of the current date/time. + def all_quarter + beginning_of_quarter..end_of_quarter + end + + # Returns a Range representing the whole year of the current date/time. + def all_year + beginning_of_year..end_of_year + end + private - def first_hour - result = yield - acts_like?(:time) ? result.change(:hour => 0) : result + 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 - result = yield - acts_like?(:time) ? result.end_of_day : result + 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) diff --git a/activesupport/lib/active_support/core_ext/date_and_time/zones.rb b/activesupport/lib/active_support/core_ext/date_and_time/zones.rb new file mode 100644 index 0000000000..96c6df9407 --- /dev/null +++ b/activesupport/lib/active_support/core_ext/date_and_time/zones.rb @@ -0,0 +1,41 @@ +module DateAndTime + module Zones + # Returns the simultaneous time in <tt>Time.zone</tt> if a zone is given or + # if Time.zone_default is set. Otherwise, it returns the current time. + # + # Time.zone = 'Hawaii' # => 'Hawaii' + # DateTime.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00 + # + # This method is similar to Time#localtime, except that it uses <tt>Time.zone</tt> as the local zone + # instead of the operating system's time zone. + # + # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, + # and the conversion will be based on that zone instead of <tt>Time.zone</tt>. + # + # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 + # DateTime.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 + # Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00 + def in_time_zone(zone = ::Time.zone) + time_zone = ::Time.find_zone! zone + time = acts_like?(:time) ? self : nil + + if time_zone + time_with_zone(time, time_zone) + else + time || self.to_time + end + end + + private + + def time_with_zone(time, zone) + if time + ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone) + else + ActiveSupport::TimeWithZone.new(nil, zone, to_time(:utc)) + end + end + end +end + |