~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activesupport/lib/active_support/core_ext/date_time/calculations.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
require 'rational'
2
 
 
3
 
module ActiveSupport #:nodoc:
4
 
  module CoreExtensions #:nodoc:
5
 
    module DateTime #:nodoc:
6
 
      # Enables the use of time calculations within DateTime itself
7
 
      module Calculations
8
 
        def self.included(base) #:nodoc:
9
 
          base.extend ClassMethods
10
 
 
11
 
          base.class_eval do
12
 
            alias_method :compare_without_coercion, :<=>
13
 
            alias_method :<=>, :compare_with_coercion
14
 
          end
15
 
        end
16
 
 
17
 
        module ClassMethods
18
 
          # DateTimes aren't aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zone
19
 
          def local_offset
20
 
            ::Time.local(2007).utc_offset.to_r / 86400
21
 
          end
22
 
 
23
 
          def current
24
 
            ::Time.zone_default ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime
25
 
          end
26
 
        end
27
 
 
28
 
        # Tells whether the DateTime object's datetime lies in the past
29
 
        def past?
30
 
          self < ::DateTime.current
31
 
        end
32
 
 
33
 
        # Tells whether the DateTime object's datetime lies in the future
34
 
        def future?
35
 
          self > ::DateTime.current
36
 
        end
37
 
 
38
 
        # Seconds since midnight: DateTime.now.seconds_since_midnight
39
 
        def seconds_since_midnight
40
 
          self.sec + (self.min * 60) + (self.hour * 3600)
41
 
        end
42
 
 
43
 
        # Returns a new DateTime where one or more of the elements have been changed according to the +options+ parameter. The time options
44
 
        # (hour, minute, sec) reset cascadingly, so if only the hour is passed, then minute and sec is set to 0. If the hour and
45
 
        # minute is passed, then sec is set to 0.
46
 
        def change(options)
47
 
          ::DateTime.civil(
48
 
            options[:year]  || self.year,
49
 
            options[:month] || self.month,
50
 
            options[:day]   || self.day,
51
 
            options[:hour]  || self.hour,
52
 
            options[:min]   || (options[:hour] ? 0 : self.min),
53
 
            options[:sec]   || ((options[:hour] || options[:min]) ? 0 : self.sec),
54
 
            options[:offset]  || self.offset,
55
 
            options[:start]  || self.start
56
 
          )
57
 
        end
58
 
 
59
 
        # Uses Date to provide precise Time calculations for years, months, and days.
60
 
        # The +options+ parameter takes a hash with any of these keys: <tt>:years</tt>,
61
 
        # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
62
 
        # <tt>:minutes</tt>, <tt>:seconds</tt>.
63
 
        def advance(options)
64
 
          d = to_date.advance(options)
65
 
          datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
66
 
          seconds_to_advance = (options[:seconds] || 0) + (options[:minutes] || 0) * 60 + (options[:hours] || 0) * 3600
67
 
          seconds_to_advance == 0 ? datetime_advanced_by_date : datetime_advanced_by_date.since(seconds_to_advance)
68
 
        end
69
 
 
70
 
        # Returns a new DateTime representing the time a number of seconds ago
71
 
        # Do not use this method in combination with x.months, use months_ago instead!
72
 
        def ago(seconds)
73
 
          self.since(-seconds)
74
 
        end
75
 
 
76
 
        # Returns a new DateTime representing the time a number of seconds since the instance time
77
 
        # Do not use this method in combination with x.months, use months_since instead!
78
 
        def since(seconds)
79
 
          self + Rational(seconds.round, 86400)
80
 
        end
81
 
        alias :in :since
82
 
 
83
 
        # Returns a new DateTime representing the start of the day (0:00)
84
 
        def beginning_of_day
85
 
          change(:hour => 0)
86
 
        end
87
 
        alias :midnight :beginning_of_day
88
 
        alias :at_midnight :beginning_of_day
89
 
        alias :at_beginning_of_day :beginning_of_day
90
 
 
91
 
        # Returns a new DateTime representing the end of the day (23:59:59)
92
 
        def end_of_day
93
 
          change(:hour => 23, :min => 59, :sec => 59)
94
 
        end
95
 
 
96
 
        # Adjusts DateTime to UTC by adding its offset value; offset is set to 0
97
 
        #
98
 
        # Example:
99
 
        #
100
 
        #   DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24))       # => Mon, 21 Feb 2005 10:11:12 -0600
101
 
        #   DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc   # => Mon, 21 Feb 2005 16:11:12 +0000
102
 
        def utc
103
 
          new_offset(0)
104
 
        end
105
 
        alias_method :getutc, :utc
106
 
 
107
 
        # Returns true if offset == 0
108
 
        def utc?
109
 
          offset == 0
110
 
        end
111
 
 
112
 
        # Returns the offset value in seconds
113
 
        def utc_offset
114
 
          (offset * 86400).to_i
115
 
        end
116
 
 
117
 
        # Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime
118
 
        def compare_with_coercion(other)
119
 
          other = other.comparable_time if other.respond_to?(:comparable_time)
120
 
          other = other.to_datetime unless other.acts_like?(:date)
121
 
          compare_without_coercion(other)
122
 
        end
123
 
      end
124
 
    end
125
 
  end
126
 
end