summaryrefslogtreecommitdiff
path: root/lib/leap_cli/core_ext/time.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/leap_cli/core_ext/time.rb')
-rw-r--r--lib/leap_cli/core_ext/time.rb86
1 files changed, 86 insertions, 0 deletions
diff --git a/lib/leap_cli/core_ext/time.rb b/lib/leap_cli/core_ext/time.rb
new file mode 100644
index 0000000..fef6c5d
--- /dev/null
+++ b/lib/leap_cli/core_ext/time.rb
@@ -0,0 +1,86 @@
+#
+# The following methods are copied from ActiveSupport's Time extension:
+# activesupport/lib/active_support/core_ext/time/calculations.rb
+#
+
+class Time
+
+ #
+ # Uses Date to provide precise Time calculations for years, months, and days
+ # according to the proleptic Gregorian calendar. The options parameter takes
+ # a hash with any of these keys: :years, :months, :weeks, :days, :hours,
+ # :minutes, :seconds.
+ #
+ def advance(options)
+ unless options[:weeks].nil?
+ options[:weeks], partial_weeks = options[:weeks].divmod(1)
+ options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
+ end
+
+ unless options[:days].nil?
+ options[:days], partial_days = options[:days].divmod(1)
+ options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
+ end
+
+ d = to_date.advance(options)
+ d = d.gregorian if d.julian?
+ time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
+ seconds_to_advance = options.fetch(:seconds, 0) +
+ options.fetch(:minutes, 0) * 60 +
+ options.fetch(:hours, 0) * 3600
+
+ if seconds_to_advance.zero?
+ time_advanced_by_date
+ else
+ time_advanced_by_date.since(seconds_to_advance)
+ end
+ end
+
+ def since(seconds)
+ self + seconds
+ rescue
+ to_datetime.since(seconds)
+ end
+
+ #
+ # Returns a new Time where one or more of the elements have been changed
+ # according to the options parameter. The time options (:hour, :min, :sec,
+ # :usec) reset cascadingly, so if only the hour is passed, then minute, sec,
+ # and usec is set to 0. If the hour and minute is passed, then sec and usec
+ # is set to 0. The options parameter takes a hash with any of these keys:
+ # :year, :month, :day, :hour, :min, :sec, :usec.
+ #
+ def change(options)
+ new_year = options.fetch(:year, year)
+ new_month = options.fetch(:month, month)
+ new_day = options.fetch(:day, day)
+ new_hour = options.fetch(:hour, hour)
+ new_min = options.fetch(:min, options[:hour] ? 0 : min)
+ new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
+ new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
+
+ if utc?
+ ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
+ elsif zone
+ ::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec, new_usec)
+ else
+ ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
+ end
+ end
+
+end
+
+class Date
+
+ # activesupport/lib/active_support/core_ext/date/calculations.rb
+ def advance(options)
+ options = options.dup
+ d = self
+ d = d >> options.delete(:years) * 12 if options[:years]
+ d = d >> options.delete(:months) if options[:months]
+ d = d + options.delete(:weeks) * 7 if options[:weeks]
+ d = d + options.delete(:days) if options[:days]
+ d
+ end
+
+end