From c3c69d90626dd5ac16231b1d53615547df678f76 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Thu, 16 Mar 2006 03:04:00 +0000 Subject: Added Time#advance to do precise time time calculations for cases where a month being approximated to 30 days won't do (closes #1860) [Rick Olson] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3887 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activesupport/lib/active_support/core_ext/numeric/time.rb | 3 +++ activesupport/lib/active_support/core_ext/time/calculations.rb | 9 +++++++++ 2 files changed, 12 insertions(+) (limited to 'activesupport/lib/active_support/core_ext') diff --git a/activesupport/lib/active_support/core_ext/numeric/time.rb b/activesupport/lib/active_support/core_ext/numeric/time.rb index a69a6c5f64..b4954e943f 100644 --- a/activesupport/lib/active_support/core_ext/numeric/time.rb +++ b/activesupport/lib/active_support/core_ext/numeric/time.rb @@ -2,6 +2,9 @@ module ActiveSupport #:nodoc: module CoreExtensions #:nodoc: module Numeric #:nodoc: # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years. + # + # If you need precise date calculations that doesn't just treat months as 30 days, then have + # a look at Time#advance. # # Some of these methods are approximations, Ruby's core # Date[http://stdlib.rubyonrails.org/libdoc/date/rdoc/index.html] and diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 6a80762a62..7c60d5bed5 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -44,6 +44,15 @@ module ActiveSupport #:nodoc: options[:usec] || ((options[:hour] || options[:min] || options[:sec]) ? 0 : self.usec) ) end + + # Uses Date to provide precise Time calculations for years, months, and days. The +options+ parameter takes a hash with + # any of these keys: :months, :days, :years. + def advance(options) + d = ::Date.new(year + (options.delete(:years) || 0), month, day) + d = d >> options.delete(:months) if options[:months] + d = d + options.delete(:days) if options[:days] + change(options.merge(:year => d.year, :month => d.month, :mday => d.day)) + end # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension # Do not use this method in combination with x.months, use months_ago instead! -- cgit v1.2.3