Class Chronos::Interval::Gregorian
In: lib/chronos/interval/gregorian.rb
Parent: Interval

A Gregorian Interval extens Interval by months. Unlike in Gregorian Durations, months exactly defined in seconds (and therefore minutes, hours, days, weeks). Internally a gregorian interval is stored as total picoseconds after days + days between the two dates and additionally the months + days after months + picoseconds after days. For

Methods

Constants

ValidFixed = [:begin, :end].freeze

Attributes

begin  [R]  The smaller of the two datetimes
end  [R]  The bigger of the two datetimes
fixed  [R]  Which end is fixed, plays a role when adding, subtracting, multiplying, dividing, …

Public Class methods

unlike new, between always creates a positive interval it will switch limit_a and limit_b if limit_a > limit_b it always fixates :begin

[Source]

    # File lib/chronos/interval/gregorian.rb, line 32
32:       def self.between(limit_a, limit_b)
33:         limit_a > limit_b ? new(limit_b, limit_a, false, :begin) : new(limit_a, limit_b, false, :begin)
34:       end

[Source]

    # File lib/chronos/interval/gregorian.rb, line 36
36:       def initialize(limit_a, limit_b, fixed=nil)
37:         super(limit_a, limit_b, fixed)
38:         picoseconds       = @end.ps_number - @begin.ps_number if @begin.time?
39:         days, picoseconds = *picoseconds.divmod(PS_IN_DAY) if @begin.time?
40:         months            = 0
41:   
42:         if @begin.date? then
43:           a                 = Datetime.new(@begin.day_number, @begin.ps_number, ::Chronos::UTC)
44:           b                 = Datetime.new(@end.day_number,   @end.ps_number,   ::Chronos::UTC)
45:           days_after_months = days+b.day_of_month-a.day_of_month
46:           months            = b.year*12+b.month-a.year*12-a.month
47: 
48:           # move 1 month forward
49:           if days_after_months < 0 then
50:             days_after_months += a.days_in_month
51:             months            -= 1
52:           end
53: 
54:           days    += b.day_number - a.day_number
55:           bsd      = a.day_of_month > b.day_of_month ||
56:                      (start_date.time? && a.day_of_month == b.day_of_month && seconds < 0)
57:           month1   = a.year*12+a.month+(bsd ? 1 : 0)
58:           month2   = b.year*12+b.month
59:           months   = month2 - month1
60:           a2y,a2m  = *(month1-1).divmod(12)
61:           a, b     = Datetime.civil(a2y, a2m+1, 1), Datetime.civil(b.year, b.month, 1)
62:   
63:           seconds_in_months = (b.day_number-a.day_number)*86400
64:           p [seconds, seconds_in_months]
65:           seconds -= seconds_in_months
66:   
67:           b2y,b2m  = *(month1+(months.div(12)*12)).divmod(12)
68:           b        = Datetime.civil(b2y, b2m+1, 1)
69:           seconds_in_years = (b.day_number-a.day_number)*86400
70:         end
71:   
72:         @gregorian_duration = Duration::Gregorian.new(months, days+overflow, picoseconds, @language)
73:       end

Public Instance methods

[Source]

    # File lib/chronos/interval/gregorian.rb, line 75
75:       def to_gregorian_duration
76:         @gregorian_duration
77:       end

[Validate]