Class: Chronos::Interval::Gregorian

Inherits:
Chronos::Interval show all
Defined in:
lib/chronos/interval/gregorian.rb

Overview

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

Constant Summary collapse

ValidFixed =
[:begin, :end].freeze

Constants inherited from Chronos::Interval

InspectFixedBegin, InspectFixedEnd

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Chronos::Interval

#+, #-, #days, #fixed_begin, #fixed_end, #format, #inspect, #picoseconds, #to_duration, #to_hash, #values_at

Constructor Details

#initialize(limit_a, limit_b, fixed = nil) ⇒ Gregorian

Returns a new instance of Gregorian.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/chronos/interval/gregorian.rb', line 36

def initialize(limit_a, limit_b, fixed=nil)
	super(limit_a, limit_b, fixed)
	picoseconds       = @end.ps_number - @begin.ps_number if @begin.time?
	days, picoseconds = *picoseconds.divmod(PS_IN_DAY) if @begin.time?
	months            = 0
	
	if @begin.date? then
		a                 = Datetime.new(@begin.day_number, @begin.ps_number, ::Chronos::UTC)
		b                 = Datetime.new(@end.day_number,   @end.ps_number,   ::Chronos::UTC)
		days_after_months = days+b.day_of_month-a.day_of_month
		months            = b.year*12+b.month-a.year*12-a.month

		# move 1 month forward
		if days_after_months < 0 then
			days_after_months += a.days_in_month
			months            -= 1
		end

		days    += b.day_number - a.day_number
		bsd      = a.day_of_month > b.day_of_month ||
							 (start_date.time? && a.day_of_month == b.day_of_month && seconds < 0)
		month1   = a.year*12+a.month+(bsd ? 1 : 0)
		month2   = b.year*12+b.month
		months   = month2 - month1
		a2y,a2m  = *(month1-1).divmod(12)
		a, b     = Datetime.civil(a2y, a2m+1, 1), Datetime.civil(b.year, b.month, 1)
	
		seconds_in_months = (b.day_number-a.day_number)*86400
		p [seconds, seconds_in_months]
		seconds -= seconds_in_months
	
		b2y,b2m  = *(month1+(months.div(12)*12)).divmod(12)
		b        = Datetime.civil(b2y, b2m+1, 1)
		seconds_in_years = (b.day_number-a.day_number)*86400
	end
	
	@gregorian_duration = Duration::Gregorian.new(months, days+overflow, picoseconds, @language)
end

Instance Attribute Details

#beginObject (readonly)

The smaller of the two datetimes



21
22
23
# File 'lib/chronos/interval/gregorian.rb', line 21

def begin
  @begin
end

#endObject (readonly)

The bigger of the two datetimes



24
25
26
# File 'lib/chronos/interval/gregorian.rb', line 24

def end
  @end
end

#fixedObject (readonly)

Which end is fixed, plays a role when adding, subtracting, multiplying, dividing, …



27
28
29
# File 'lib/chronos/interval/gregorian.rb', line 27

def fixed
  @fixed
end

Class Method Details

.between(limit_a, limit_b) ⇒ Object

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



32
33
34
# File 'lib/chronos/interval/gregorian.rb', line 32

def self.between(limit_a, limit_b)
	limit_a > limit_b ? new(limit_b, limit_a, false, :begin) : new(limit_a, limit_b, false, :begin)
end

Instance Method Details

#to_gregorian_durationObject



75
76
77
# File 'lib/chronos/interval/gregorian.rb', line 75

def to_gregorian_duration
	@gregorian_duration
end