Duration, integer interval access.

This commit is contained in:
Peter Camilleri 2015-07-12 21:34:28 -04:00
parent edd703d4b0
commit 7d490f8624
3 changed files with 162 additions and 24 deletions

View file

@ -37,6 +37,76 @@ class TimeLibraryTester < Minitest::Test
foorth_equal('Duration .sec_per_hour', [ 3_600])
foorth_equal('Duration .sec_per_min', [ 60])
foorth_equal('Duration .sec_per_sec', [ 1])
foorth_equal('Duration .sec_per_year .to_duration .years ', [1])
foorth_equal('Duration .sec_per_year 3/2 * .to_duration .years ', [1])
foorth_equal('Duration .sec_per_year 2 * .to_duration .years ', [2])
foorth_equal('Duration .sec_per_year .to_duration .months ', [0])
foorth_equal('Duration .sec_per_year 3/2 * .to_duration .months ', [6])
foorth_equal('Duration .sec_per_year 2 * .to_duration .months ', [0])
foorth_equal('Duration .sec_per_month .to_duration .months ', [1])
foorth_equal('Duration .sec_per_month 3/2 * .to_duration .months ', [1])
foorth_equal('Duration .sec_per_month 2 * .to_duration .months ', [2])
foorth_equal('Duration .sec_per_year .to_duration .days ', [0])
foorth_equal('Duration .sec_per_year 3/2 * .to_duration .days ', [0])
foorth_equal('Duration .sec_per_year 2 * .to_duration .days ', [0])
foorth_equal('Duration .sec_per_month .to_duration .days ', [0])
foorth_equal('Duration .sec_per_month 3/2 * .to_duration .days ', [15])
foorth_equal('Duration .sec_per_month 2 * .to_duration .days ', [0])
foorth_equal('Duration .sec_per_day .to_duration .days ', [1])
foorth_equal('Duration .sec_per_day 3/2 * .to_duration .days ', [1])
foorth_equal('Duration .sec_per_day 2 * .to_duration .days ', [2])
foorth_equal('Duration .sec_per_year .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_year 3/2 * .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_year 2 * .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_month .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_month 3/2 * .to_duration .hours ', [5])
foorth_equal('Duration .sec_per_month 2 * .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_day .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_day 3/2 * .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_day 2 * .to_duration .hours ', [0])
foorth_equal('Duration .sec_per_hour .to_duration .hours ', [1])
foorth_equal('Duration .sec_per_hour 3/2 * .to_duration .hours ', [1])
foorth_equal('Duration .sec_per_hour 2 * .to_duration .hours ', [2])
foorth_equal('Duration .sec_per_year .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_year 3/2 * .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_year 2 * .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_month .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_month 3/2 * .to_duration .minutes', [14])
foorth_equal('Duration .sec_per_month 2 * .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_day .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_day 3/2 * .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_day 2 * .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_hour .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_hour 3/2 * .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_hour 2 * .to_duration .minutes', [0])
foorth_equal('Duration .sec_per_min .to_duration .minutes', [1])
foorth_equal('Duration .sec_per_min 3/2 * .to_duration .minutes', [1])
foorth_equal('Duration .sec_per_min 2 * .to_duration .minutes', [2])
foorth_equal('Duration .sec_per_year .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_year 3/2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_year 2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_month .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_month 3/2 * .to_duration .seconds', [33])
foorth_equal('Duration .sec_per_month 2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_day .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_day 3/2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_day 2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_hour .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_hour 3/2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_hour 2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_min .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_min 3/2 * .to_duration .seconds', [0])
foorth_equal('Duration .sec_per_min 2 * .to_duration .seconds', [0])
foorth_equal(' 1 .to_duration .seconds', [1])
foorth_equal(' 3/2 .to_duration .seconds', [1.5])
foorth_equal(' 2 .to_duration .seconds', [2])
end
def test_converting_to_time
@ -101,9 +171,12 @@ class TimeLibraryTester < Minitest::Test
foorth_equal('5 .to_duration .to_r', ["5/1".to_r])
foorth_equal('5 .to_duration .to_f', [5.0])
foorth_equal('5 .to_duration .to_a', [[0, 0, 0, 0, 0, 5]])
foorth_equal('60 .to_duration .to_a', [[0, 0, 0, 0, 1, 0]])
foorth_equal('31556952 .to_duration .to_a', [[1, 0, 0, 0, 0, 0]])
foorth_equal('0.4 .to_duration .to_a', [[0, 0, 0, 0, 0, 0.4]])
foorth_equal('5.4 .to_duration .to_a', [[0, 0, 0, 0, 0, 5.4]])
foorth_equal('5 .to_duration .to_a', [[0, 0, 0, 0, 0, 5 ]])
foorth_equal('60 .to_duration .to_a', [[0, 0, 0, 0, 1, 0 ]])
foorth_equal('31556952 .to_duration .to_a', [[1, 0, 0, 0, 0, 0 ]])
foorth_equal('315569523/10 .to_duration .to_a', [[1, 0, 0, 0, 0, 0.3]])
end
@ -125,8 +198,8 @@ class TimeLibraryTester < Minitest::Test
foorth_equal("0 .to_duration! 0 .to_duration <>", [false])
foorth_equal("1 .to_duration 0 .to_duration <>", [true])
foorth_equal("0 .to_duration 1 .to_duration <>", [true])
foorth_equal("1 .to_duration 0 .to_duration <>", [true])
foorth_equal("0 .to_duration 1 .to_duration <>", [true])
foorth_equal("0 .to_duration 0 <>", [false])
foorth_equal("1 .to_duration 0 <>", [true])

View file

@ -6,20 +6,50 @@ module XfOOrth
#Intervals support for the \Duration class.
class Duration
A_Second = 1
A_Minute = 60 * A_Second
An_Hour = 60 * A_Minute
A_Day = 24 * An_Hour
A_Month = Rational(365_2425, 120000) * A_Day
A_Year = Rational(365_2425, 10000) * A_Day
A_SECOND = 1
A_MINUTE = 60 * A_SECOND
AN_HOUR = 60 * A_MINUTE
A_DAY = 24 * AN_HOUR
A_MONTH = Rational(365_2425, 120000) * A_DAY
A_YEAR = 12 * A_MONTH
Intervals = [A_Year, A_Month, A_Day, An_Hour, A_Minute, A_Second]
Intervals = [A_YEAR, A_MONTH, A_DAY, AN_HOUR, A_MINUTE, A_SECOND]
#Find the largest interval for this duration
def largest_interval
(0..5).detect {|idx| Intervals[idx] <= period} || 5
end
#How many years in this duration?
def years
(@period/A_YEAR).to_i
end
#How many months in this duration?
def months
((@period - (@period/A_YEAR).to_i*A_YEAR)/A_MONTH).to_i
end
#How many days in this duration?
def days
self.to_a[2]
end
#How many hours in this duration?
def hours
self.to_a[3]
end
#How many minutes in this duration?
def minutes
self.to_a[4]
end
#How many seconds in this duration?
def seconds
self.to_a[5]
end
end
@ -30,27 +60,27 @@ module XfOOrth
})
Duration.create_exclusive_method('.sec_per_year', TosSpec, [], &lambda {|vm|
vm.push(Duration::A_Year)
vm.push(Duration::A_YEAR)
})
Duration.create_exclusive_method('.sec_per_month', TosSpec, [], &lambda {|vm|
vm.push(Duration::A_Month)
vm.push(Duration::A_MONTH)
})
Duration.create_exclusive_method('.sec_per_day', TosSpec, [], &lambda {|vm|
vm.push(Duration::A_Day)
vm.push(Duration::A_DAY)
})
Duration.create_exclusive_method('.sec_per_hour', TosSpec, [], &lambda {|vm|
vm.push(Duration::An_Hour)
vm.push(Duration::AN_HOUR)
})
Duration.create_exclusive_method('.sec_per_min', TosSpec, [], &lambda {|vm|
vm.push(Duration::A_Minute)
vm.push(Duration::A_MINUTE)
})
Duration.create_exclusive_method('.sec_per_sec', TosSpec, [], &lambda {|vm|
vm.push(Duration::A_Second)
vm.push(Duration::A_SECOND)
})
@ -61,4 +91,35 @@ module XfOOrth
vm.push(self.largest_interval)
})
#[a_duration] .years [an_integer]
Duration.create_shared_method('.years', TosSpec, [], &lambda {|vm|
vm.push(self.years)
})
#[a_duration] .months [an_integer]
Duration.create_shared_method('.months', TosSpec, [], &lambda {|vm|
vm.push(self.months)
})
#[a_duration] .days [an_integer]
Duration.create_shared_method('.days', TosSpec, [], &lambda {|vm|
vm.push(self.days)
})
#[a_duration] .hours [an_integer]
Duration.create_shared_method('.hours', TosSpec, [], &lambda {|vm|
vm.push(self.hours)
})
#[a_duration] .minutes [an_integer]
Duration.create_shared_method('.minutes', TosSpec, [], &lambda {|vm|
vm.push(self.minutes)
})
#[a_duration] .seconds [an_integer]
Duration.create_shared_method('.seconds', TosSpec, [], &lambda {|vm|
vm.push(self.seconds)
})
end

View file

@ -18,7 +18,7 @@ module XfOOrth
#<br>Parameters
#* period - The period of time of the duration.
def initialize(period)
@period = period
@period = period.rationalize
end
#Coerce the argument to match my type.
@ -45,9 +45,13 @@ module XfOOrth
temp = @period
Duration::Intervals.map do |interval|
value = (temp / interval).to_i
temp -= value * interval
value
if interval > A_SECOND
value = (temp / interval).to_i
temp -= value * interval
value
else
temp.to_f
end
end
end
@ -78,7 +82,7 @@ module XfOOrth
#[number] .to_duration [a_duration]
Object.create_shared_method('.to_duration', TosSpec, [], &lambda {|vm|
begin
vm.push(Duration.new(Rational(self)))
vm.push(Duration.new(self))
rescue
vm.push(nil)
end
@ -87,7 +91,7 @@ module XfOOrth
#[number] .to_duration! [a_duration]
Object.create_shared_method('.to_duration!', TosSpec, [], &lambda {|vm|
begin
vm.push(Duration.new(Rational(self)))
vm.push(Duration.new(self))
rescue
error "F40: Cannot convert #{self.to_s} to a Duration instance"
end