diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext/time')
4 files changed, 41 insertions, 50 deletions
diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 372dd69212..5e433f5dd9 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -78,7 +78,7 @@ class Time options[:hour] || hour, options[:min] || (options[:hour] ? 0 : min), options[:sec] || ((options[:hour] || options[:min]) ? 0 : sec), - options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : usec) + options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000)) ) end @@ -161,27 +161,46 @@ class Time months_since(1) end - # Returns a new Time representing the "start" of this week (Monday, 0:00) - def beginning_of_week - days_to_monday = wday!=0 ? wday-1 : 6 - (self - days_to_monday.days).midnight + # Returns number of days to start of this week, week starts on start_day (default is :monday). + def days_to_week_start(start_day = :monday) + start_day_number = DAYS_INTO_WEEK[start_day] + current_day_number = wday != 0 ? wday - 1 : 6 + days_span = current_day_number - start_day_number + days_span >= 0 ? days_span : 7 + days_span + end + + # Returns a new Time representing the "start" of this week, week starts on start_day (default is :monday, i.e. Monday, 0:00). + def beginning_of_week(start_day = :monday) + days_to_start = days_to_week_start(start_day) + (self - days_to_start.days).midnight end - alias :monday :beginning_of_week alias :at_beginning_of_week :beginning_of_week - # Returns a new Time representing the end of this week, (end of Sunday) - def end_of_week - days_to_sunday = wday!=0 ? 7-wday : 0 - (self + days_to_sunday.days).end_of_day + # Returns a new +Date+/+DateTime+ representing the start of this week. Week is + # assumed to start on a Monday. +DateTime+ objects have their time set to 0:00. + def monday + beginning_of_week + end + + # Returns a new Time representing the end of this week, week starts on start_day (default is :monday, i.e. end of Sunday). + def end_of_week(start_day = :monday) + days_to_end = 6 - days_to_week_start(start_day) + (self + days_to_end.days).end_of_day 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). + # Returns a new +Date+/+DateTime+ representing the end of this week. Week is + # assumed to start on a Monday. +DateTime+ objects have their time set to 23:59:59. + def sunday + end_of_week + end + + # 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). + # 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) end @@ -312,4 +331,14 @@ class Time end alias_method :compare_without_coercion, :<=> alias_method :<=>, :compare_with_coercion + + # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances + # can be eql? to an equivalent Time + def eql_with_coercion(other) + # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison + other = other.comparable_time if other.respond_to?(:comparable_time) + eql_without_coercion(other) + end + alias_method :eql_without_coercion, :eql? + alias_method :eql?, :eql_with_coercion end diff --git a/activesupport/lib/active_support/core_ext/time/conversions.rb b/activesupport/lib/active_support/core_ext/time/conversions.rb index 49ac18d245..5a17fc1afa 100644 --- a/activesupport/lib/active_support/core_ext/time/conversions.rb +++ b/activesupport/lib/active_support/core_ext/time/conversions.rb @@ -1,5 +1,4 @@ require 'active_support/inflector/methods' -require 'active_support/core_ext/time/publicize_conversion_methods' require 'active_support/values/time_zone' class Time diff --git a/activesupport/lib/active_support/core_ext/time/marshal.rb b/activesupport/lib/active_support/core_ext/time/marshal.rb index 457d3f5b62..1bf622d6a6 100644 --- a/activesupport/lib/active_support/core_ext/time/marshal.rb +++ b/activesupport/lib/active_support/core_ext/time/marshal.rb @@ -1,30 +1,3 @@ -# Pre-1.9 versions of Ruby have a bug with marshaling Time instances, where utc instances are -# unmarshalled in the local zone, instead of utc. We're layering behavior on the _dump and _load -# methods so that utc instances can be flagged on dump, and coerced back to utc on load. -if !Marshal.load(Marshal.dump(Time.now.utc)).utc? - class Time - class << self - alias_method :_load_without_utc_flag, :_load - def _load(marshaled_time) - time = _load_without_utc_flag(marshaled_time) - time.instance_eval do - if defined?(@marshal_with_utc_coercion) - val = remove_instance_variable("@marshal_with_utc_coercion") - end - val ? utc : self - end - end - end - - alias_method :_dump_without_utc_flag, :_dump - def _dump(*args) - obj = dup - obj.instance_variable_set('@marshal_with_utc_coercion', utc?) - obj._dump_without_utc_flag(*args) - end - end -end - # Ruby 1.9.2 adds utc_offset and zone to Time, but marshaling only # preserves utc_offset. Preserve zone also, even though it may not # work in some edge cases. diff --git a/activesupport/lib/active_support/core_ext/time/publicize_conversion_methods.rb b/activesupport/lib/active_support/core_ext/time/publicize_conversion_methods.rb deleted file mode 100644 index e1878d3c20..0000000000 --- a/activesupport/lib/active_support/core_ext/time/publicize_conversion_methods.rb +++ /dev/null @@ -1,10 +0,0 @@ -require 'date' - -class Time - # Ruby 1.8-cvs and early 1.9 series define private Time#to_date - %w(to_date to_datetime).each do |method| - if private_instance_methods.include?(method) || private_instance_methods.include?(method.to_sym) - public method - end - end -end |