added jj_temporal source code
This commit is contained in:
229
jj_temporal/jj_t/classes/abstract_duration.e
Normal file
229
jj_temporal/jj_t/classes/abstract_duration.e
Normal file
@@ -0,0 +1,229 @@
|
||||
note
|
||||
description: "[
|
||||
Notion of a duration of time such as 2 hours, or 3 years, etc.
|
||||
]"
|
||||
names: "abstract_duration, duration"
|
||||
date: "1 Jan 99"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
deferred class
|
||||
ABSTRACT_DURATION
|
||||
|
||||
inherit
|
||||
COMPARABLE
|
||||
|
||||
feature -- Access
|
||||
|
||||
feature -- Access
|
||||
|
||||
as_string: STRING
|
||||
-- The time represented as a string, ideally with not extra characters.
|
||||
deferred
|
||||
end
|
||||
|
||||
negative: like Current
|
||||
-- The negative value of this duration
|
||||
do
|
||||
Result := twin
|
||||
Result.negate
|
||||
ensure
|
||||
negative_result: Current > zero implies Result < zero
|
||||
positive_result: Current < zero implies Result > zero
|
||||
end
|
||||
|
||||
one: like Current
|
||||
-- Neutral element for "*" and "/"
|
||||
deferred
|
||||
ensure
|
||||
result_exists: Result /= Void
|
||||
valid_result: Result.is_one
|
||||
end
|
||||
|
||||
zero: like Current
|
||||
-- Neutral element for "+" and "-"
|
||||
deferred
|
||||
ensure
|
||||
result_exists: Result /= Void
|
||||
good_result: Result.is_zero
|
||||
end
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
is_zero: BOOLEAN
|
||||
-- Is this duration of 0 length?
|
||||
do
|
||||
Result := equal (Current, zero)
|
||||
ensure
|
||||
valid_result: Result implies equal (Current, zero)
|
||||
end
|
||||
|
||||
is_one: BOOLEAN
|
||||
-- Is this duration neutral for '*' and '/'?
|
||||
do
|
||||
Result := equal (Current, one)
|
||||
ensure
|
||||
valid_result: Result implies equal (Current, one)
|
||||
end
|
||||
|
||||
is_negative: BOOLEAN
|
||||
-- Is current less than the 'zero' duration?
|
||||
do
|
||||
Result := Current < zero
|
||||
ensure
|
||||
valid_result: Result implies Current < zero
|
||||
end
|
||||
|
||||
feature -- Element Change
|
||||
|
||||
set_zero
|
||||
-- Make the duration have zero length.
|
||||
deferred
|
||||
ensure
|
||||
is_zero: is_zero
|
||||
end
|
||||
|
||||
|
||||
negate
|
||||
-- Reverses the sign.
|
||||
deferred
|
||||
ensure
|
||||
positive_implication: not is_negative implies old is_negative
|
||||
negative_implication: is_negative implies not old is_negative
|
||||
end
|
||||
|
||||
add (other: like Current)
|
||||
-- Add other other to Current.
|
||||
require
|
||||
other_exists: other /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
sub (other: like Current)
|
||||
-- Subtract other from Current
|
||||
require
|
||||
other_exists: other /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
multiply (r: DOUBLE)
|
||||
-- Multiply by a factor of 'r'.
|
||||
deferred
|
||||
end
|
||||
|
||||
divide (r: DOUBLE)
|
||||
-- Divide by 'r'.
|
||||
require
|
||||
not_zero_devisor: r /= 0
|
||||
deferred
|
||||
end
|
||||
|
||||
div (i: INTEGER)
|
||||
-- Integer division.
|
||||
require
|
||||
not_zero_devisor: i /= 0
|
||||
deferred
|
||||
end
|
||||
|
||||
mod (i: INTEGER)
|
||||
-- Modulo.
|
||||
require
|
||||
not_zero_devisor: i /= 0
|
||||
deferred
|
||||
end
|
||||
|
||||
percent_of (other: like Current): DOUBLE
|
||||
-- What percent of other in length is this one?
|
||||
-- For example: is current duration at least twice as long as other?
|
||||
require
|
||||
other_exists: other /= Void
|
||||
other_not_zero: not other.is_zero
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
identity alias "+": like Current
|
||||
-- Just a clone of Current. Included for symetry.
|
||||
do
|
||||
Result := twin
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
oposite alias "-": like Current
|
||||
-- Invert the sign of other.
|
||||
do
|
||||
Result := twin
|
||||
Result.negate
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
plus alias "+" (other: like Current): like Current
|
||||
-- Sum of current and other.
|
||||
do
|
||||
Result := twin
|
||||
Result.add (other)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
minus alias "-" (other: like Current): like Current
|
||||
-- Difference of Current and other.
|
||||
do
|
||||
Result := twin
|
||||
Result.sub (other)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
product alias "*" (r: DOUBLE): like Current
|
||||
-- Product of Current and 'r'.
|
||||
-- Multiply by a factor of 'r'.
|
||||
do
|
||||
Result := twin
|
||||
Result.multiply (r)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
quotient alias "/" (r: DOUBLE): like Current
|
||||
-- Quotent of Current by 'r'.
|
||||
require
|
||||
not_zero_devisor: r /= 0
|
||||
do
|
||||
Result := twin
|
||||
Result.divide (r)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
integer_quotient alias "//" (i: INTEGER): like Current
|
||||
-- Integer division of Current by 'i'.
|
||||
require
|
||||
not_zero_devisor: i /= 0
|
||||
do
|
||||
Result := twin
|
||||
Result.div (i)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
integer_remainder alias "\\" (i: INTEGER): like Current
|
||||
-- Modulo of Current by 'i'.
|
||||
require
|
||||
not_zero_devisor: i /= 0
|
||||
do
|
||||
Result := twin
|
||||
Result.mod (i)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
end
|
||||
|
387
jj_temporal/jj_t/classes/abstract_interval.e
Normal file
387
jj_temporal/jj_t/classes/abstract_interval.e
Normal file
@@ -0,0 +1,387 @@
|
||||
note
|
||||
description: "[
|
||||
Notion of a span of time consisting of a start-time, a
|
||||
finish-time and a duration. Positive durations only.
|
||||
]"
|
||||
names: "abstract_interval, time_span, time_interval, span"
|
||||
date: "1 Jan 99"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
deferred class
|
||||
ABSTRACT_INTERVAL
|
||||
|
||||
inherit
|
||||
|
||||
COMPARABLE
|
||||
undefine
|
||||
default_create
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
start: like time_anchor
|
||||
-- Beginning moment of the time span and anchor for class.
|
||||
do
|
||||
Result := start_imp.twin
|
||||
ensure
|
||||
result_exists: Result /= Void
|
||||
end
|
||||
|
||||
finish: like time_anchor
|
||||
-- Ending moment of the time span.
|
||||
do
|
||||
Result := finish_imp.twin
|
||||
ensure
|
||||
result_exists: Result /= Void
|
||||
end
|
||||
|
||||
duration: like duration_anchor
|
||||
-- Length of time span.
|
||||
do
|
||||
Result := finish.time_between (start)
|
||||
ensure
|
||||
result_exists: Result /= Void
|
||||
end
|
||||
|
||||
feature -- Element Change
|
||||
|
||||
set_start_finish (a_start_time, a_finish_time: like time_anchor)
|
||||
-- Set the `start' and `finish' times.
|
||||
require
|
||||
times_exists: a_start_time /= Void and a_finish_time /= Void
|
||||
valid_times: a_start_time <= a_finish_time
|
||||
do
|
||||
start_imp := a_start_time.twin
|
||||
finish_imp := a_finish_time.twin
|
||||
ensure
|
||||
start_was_set: equal (start, a_start_time)
|
||||
finish_was_set: equal (finish, a_finish_time)
|
||||
end
|
||||
|
||||
set_start_duration (a_start_time: like time_anchor; a_duration: like duration_anchor)
|
||||
-- Set the `start' time and the `duration'.
|
||||
require
|
||||
start_time_exists: a_start_time /= Void
|
||||
duration_exists: a_duration /= Void
|
||||
positive_duration: not a_duration.is_negative
|
||||
do
|
||||
start_imp := a_start_time.twin
|
||||
finish_imp := a_start_time + a_duration
|
||||
ensure
|
||||
start_was_set: equal (start, a_start_time)
|
||||
duration_was_set: equal (duration, a_duration)
|
||||
end
|
||||
|
||||
set_duration_finish (a_duration: like duration_anchor; a_finish_time: like time_anchor)
|
||||
-- Set the `duration' and `finish' time.
|
||||
require
|
||||
duration_exists: a_duration /= Void
|
||||
positive_duration: not a_duration.is_negative
|
||||
finish_time_exists: a_finish_time /= Void
|
||||
do
|
||||
start_imp := a_finish_time - a_duration
|
||||
finish_imp := a_finish_time.twin
|
||||
ensure
|
||||
finish_was_set: equal (finish, a_finish_time)
|
||||
duration_was_set: equal (duration, a_duration)
|
||||
end
|
||||
|
||||
move (a_duration: like duration_anchor)
|
||||
-- Change the `start' and `finish' times by moving the
|
||||
-- interval by the amount represented by `a_duration'.
|
||||
require
|
||||
duration_exists: a_duration /= Void
|
||||
do
|
||||
start_imp.add_duration (a_duration)
|
||||
finish_imp.add_duration (a_duration)
|
||||
ensure
|
||||
duration_unchanged: equal (duration, old duration)
|
||||
end
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
-- Does current interval start before other or if they start at the
|
||||
-- same time, does Current end before the other?
|
||||
do
|
||||
if (start < other.start) or else
|
||||
(start.is_equal (other.start) and then finish < other.finish) then
|
||||
Result := true
|
||||
end
|
||||
ensure then
|
||||
less_than_definition: Result implies (start < other.start or else
|
||||
(start.is_equal (other.start) and then finish < other.finish))
|
||||
end
|
||||
|
||||
meets (other: like Current): BOOLEAN
|
||||
-- x.meets(y) |-----x----->|
|
||||
-- y.is_met_by(x) |-----y----->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := equal (finish, other.start)
|
||||
ensure
|
||||
Result implies equal (finish, other.start)
|
||||
Result implies Current < other
|
||||
end
|
||||
|
||||
is_met_by (other: like Current): BOOLEAN
|
||||
-- x.meets(y) |-----x----->|
|
||||
-- y.is_met_by(x) |-----y----->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := equal (start, other.finish)
|
||||
ensure
|
||||
Result implies equal (start, other.finish)
|
||||
Result implies other < Current
|
||||
end
|
||||
|
||||
is_before (other: like Current): BOOLEAN
|
||||
-- x.is_before(y) |-----x----->|
|
||||
-- y.is_after(x) |-----y----->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := finish < other.start
|
||||
ensure
|
||||
Result implies finish.is_before (other)
|
||||
Result implies Current < other
|
||||
end
|
||||
|
||||
is_after (other: like Current): BOOLEAN
|
||||
-- x.is_before(y) |-----x----->|
|
||||
-- y.is_after(x) |-----y----->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := start > other.finish
|
||||
ensure
|
||||
Result implies start.is_after (other)
|
||||
Result implies other < Current
|
||||
end
|
||||
|
||||
includes (other: like Current): BOOLEAN
|
||||
-- x.includes(y) |-----x----->|
|
||||
-- y.is_included_by(x) |--y-->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := other.start.belongs (Current) and
|
||||
other.finish.belongs (Current)
|
||||
ensure
|
||||
Result implies other.start.belongs (Current);
|
||||
Result implies other.finish.belongs (Current)
|
||||
end
|
||||
|
||||
is_included_by (other: like Current): BOOLEAN
|
||||
-- x.includes(y) |-----x----->|
|
||||
-- y.is_included_by(x) |--y-->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := start.belongs (other) and finish.belongs (other)
|
||||
ensure
|
||||
Result implies start.belongs (other);
|
||||
Result implies finish.belongs (other);
|
||||
end
|
||||
|
||||
overlaps (other: like Current): BOOLEAN
|
||||
-- x.overlaps(y) |-----x----->|
|
||||
-- y.is_overlapped_by(x) |--y-->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := finish.belongs (other)
|
||||
ensure
|
||||
Result implies finish.belongs (other)
|
||||
end
|
||||
|
||||
is_overlapped_by (other: like Current): BOOLEAN
|
||||
-- x.overlaps(y) |-----x----->|
|
||||
-- y.is_overlapped_by(x) |--y-->|
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := other.finish.belongs (Current)
|
||||
ensure
|
||||
Result implies other.finish.belongs (Current)
|
||||
end
|
||||
|
||||
intersects (other: like Current): BOOLEAN
|
||||
-- Do the two intervals have a least one time point in common?
|
||||
require
|
||||
other_exists: other /= Void
|
||||
do
|
||||
Result := meets (other) or is_met_by (other) or else
|
||||
includes (other) or is_included_by (other) or else
|
||||
overlaps (other) or is_overlapped_by (other)
|
||||
ensure
|
||||
Result implies meets (other) or is_met_by (other) or else
|
||||
includes (other) or is_included_by (other) or else
|
||||
overlaps (other) or is_overlapped_by (other)
|
||||
end
|
||||
|
||||
feature -- Transformation
|
||||
|
||||
unite (other: like Current)
|
||||
-- Transform into the union between this interval and the other.
|
||||
-- |-------------x------------->|
|
||||
-- |-------------y------------->|
|
||||
-- |------------x.union(y)----------->|
|
||||
-- Only valid if at least one time point common to both.
|
||||
require
|
||||
other_exists: other /= Void
|
||||
intersecting_intervals: intersects (other)
|
||||
local
|
||||
temp_start: like time_anchor
|
||||
temp_finish: like finish
|
||||
do
|
||||
temp_start := start.min (other.start)
|
||||
temp_finish := finish.max (other.finish)
|
||||
set_start_finish (temp_start, temp_finish);
|
||||
ensure
|
||||
valid_result: equal (start, old start.min(other.start)) and
|
||||
equal (finish, old finish.max(other.finish))
|
||||
end
|
||||
|
||||
intersect (other: like Current)
|
||||
-- Transform into the intersection of this interval and the other.
|
||||
-- |-------------x------------->|
|
||||
-- |-------------y------------->|
|
||||
-- |--x.intersection(y)-->|
|
||||
-- Only valid if at least one time point common to both.
|
||||
require
|
||||
other_exists: other /= Void
|
||||
intersecting_intervals: intersects (other)
|
||||
local
|
||||
temp_start: like time_anchor
|
||||
temp_finish: like finish
|
||||
do
|
||||
temp_start := start.max (other.start)
|
||||
temp_finish := finish.min (other.finish)
|
||||
set_start_finish (temp_start, temp_finish);
|
||||
ensure
|
||||
valid_result: equal (start, old start.max(other.start)) and
|
||||
equal (finish, old finish.min(other.finish))
|
||||
end
|
||||
|
||||
split (a_time: like time_anchor): like Current
|
||||
-- Transform by splitting the interval at 'a_time'.
|
||||
-- Result is the interval after 'a_time'.
|
||||
-- |
|
||||
-- time
|
||||
-- |
|
||||
-- V
|
||||
-- |-----Current----------------->|
|
||||
-- |---Current--->|----Result---->|
|
||||
-- Only valid if time is within the interval.
|
||||
require
|
||||
time_exists: a_time /= Void
|
||||
time_in_interval: a_time.belongs (Current)
|
||||
do
|
||||
Result := twin
|
||||
set_start_finish (start, a_time)
|
||||
Result.set_start_finish (a_time, Result.finish)
|
||||
ensure
|
||||
closure: equal (old Current, Result.union (Current))
|
||||
meets_result: Current.meets (Result)
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
union (other: like Current): like Current
|
||||
-- The union between this interval and the other.
|
||||
-- |-------------x------------->|
|
||||
-- |-------------y------------->|
|
||||
-- |------------x.union(y)----------->|
|
||||
-- Only valid if at least one time point common to both.
|
||||
require
|
||||
other_exists: other /= Void
|
||||
intersecting_intervals: intersects (other)
|
||||
do
|
||||
Result := twin
|
||||
Result.unite (other)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
valid_result: equal (Result.start, start.min(other.start)) and
|
||||
equal (Result.finish, finish.max(other.finish))
|
||||
end
|
||||
|
||||
intersection (other: like Current): like Current
|
||||
-- The intersection of this interval and the other.
|
||||
-- |-------------x------------->|
|
||||
-- |-------------y------------->|
|
||||
-- |--x.intersection(y)-->|
|
||||
-- Only valid if at least one time point common to both.
|
||||
require
|
||||
other_exists: other /= Void
|
||||
intersecting_intervals: intersects (other)
|
||||
do
|
||||
Result := twin
|
||||
Result.intersect (other)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
valid_result: equal (Result.start, start.max (other.start)) and
|
||||
equal (Result.finish, finish.min(other.finish))
|
||||
end
|
||||
|
||||
time_at_percent (a_ratio: DOUBLE): like time_anchor
|
||||
-- Time based on some percentage of this interval.
|
||||
-- Example 1: if 'a_ratio' is 0.0 then result = 'start'; if
|
||||
-- 'a_ratio' is 0.5 then resulting time is 1/2 the distance
|
||||
-- from start to finish; if 'a_ratio' is 2.0 then resulting time
|
||||
-- is at twice the duration from start to finish.
|
||||
do
|
||||
Result := start + (duration * a_ratio)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
start_imp: like time_anchor
|
||||
-- Used internally to prevent changes to `start' which could otherwise
|
||||
-- be induced by calls to a _TIME.
|
||||
|
||||
finish_imp: like time_anchor
|
||||
-- Used internally to prevent changes to `finish' which could otherwise
|
||||
-- be induced by calls to a _TIME.
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
time_anchor: ABSTRACT_TIME
|
||||
-- Anchor for features using times.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
duration_anchor: ABSTRACT_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
is_initialized: start_imp /= Void and finish_imp /= Void
|
||||
start_before_finish: start <= finish
|
||||
positive_duration: not duration.is_negative
|
||||
|
||||
end
|
273
jj_temporal/jj_t/classes/abstract_time.e
Normal file
273
jj_temporal/jj_t/classes/abstract_time.e
Normal file
@@ -0,0 +1,273 @@
|
||||
note
|
||||
description: "[
|
||||
Notion of a time, such as <1 Jan 98> or <10:30 P.M.> or <the moment of creation>, etc.
|
||||
]"
|
||||
names: "abstract_time, time, date"
|
||||
date: "1 Jan 99"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
deferred class
|
||||
ABSTRACT_TIME
|
||||
|
||||
inherit
|
||||
COMPARABLE
|
||||
|
||||
feature -- Access
|
||||
|
||||
as_string: STRING
|
||||
-- The time represented as a string, ideally with not extra characters.
|
||||
deferred
|
||||
end
|
||||
|
||||
as_integer: INTEGER
|
||||
-- The time as represented by an INTEGER.
|
||||
require
|
||||
is_representable: is_representable_as_integer
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
set_now
|
||||
-- Set current time according to timezone.
|
||||
deferred
|
||||
end
|
||||
|
||||
set_now_utc
|
||||
-- Set the current object to today's date in utc format.
|
||||
deferred
|
||||
end
|
||||
|
||||
set_now_utc_fine
|
||||
-- Set the current object to today's date in utc format.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
from_string (a_string: STRING)
|
||||
-- Change Current to the time represented by `a_string'.
|
||||
-- It must be in the format as provided by `as_string'.
|
||||
require
|
||||
valid_string_representation: is_valid_string_representation (a_string)
|
||||
deferred
|
||||
end
|
||||
|
||||
from_integer (a_integer: INTEGER)
|
||||
-- Change Current to the time represented by `a_integer'.
|
||||
require
|
||||
valid_integer_representation: is_valid_integer_representation (a_integer)
|
||||
deferred
|
||||
end
|
||||
|
||||
add_duration (a_duration: like duration_anchor)
|
||||
-- adds a duration to Current time
|
||||
require
|
||||
duration_exists: a_duration /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
plus alias "+" (a_duration: like duration_anchor): like Current
|
||||
-- same as add_duration except returns a new time
|
||||
require
|
||||
duration_exists: a_duration /= Void
|
||||
do
|
||||
Result := twin
|
||||
Result.add_duration (a_duration)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
minus alias "-" (a_duration: like duration_anchor): like Current
|
||||
-- same as adding a negative duration except returns a new time
|
||||
require
|
||||
duration_exists: a_duration /= Void
|
||||
do
|
||||
Result := twin
|
||||
Result.add_duration (a_duration.negative)
|
||||
ensure
|
||||
no_side_effect: equal (Current, old Current)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_representable_as_integer: BOOLEAN
|
||||
-- Can Current be represented as an integer?
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Querry
|
||||
|
||||
is_before (a_interval: like interval_anchor): BOOLEAN
|
||||
-- Is this time before the interval?
|
||||
require
|
||||
interval_exists: a_interval /= Void
|
||||
do
|
||||
Result := Current < a_interval.start
|
||||
ensure
|
||||
valid_result: Result implies Current < a_interval.start
|
||||
end
|
||||
|
||||
is_after (a_interval: like interval_anchor): BOOLEAN
|
||||
-- Is this time after the interval?
|
||||
require
|
||||
interval_exists: a_interval /= Void
|
||||
do
|
||||
Result := Current > a_interval.finish
|
||||
ensure
|
||||
valid_result: Result implies Current > a_interval.finish
|
||||
end
|
||||
|
||||
belongs (a_interval: like interval_anchor): BOOLEAN
|
||||
-- Does this time fall somewhere during the interval?
|
||||
require
|
||||
interval_exists: a_interval /= Void
|
||||
do
|
||||
Result := Current >= a_interval.start and Current <= a_interval.finish
|
||||
ensure
|
||||
valid_result: Result implies Current >= a_interval.start and Current <= a_interval.finish
|
||||
end
|
||||
|
||||
is_between (time_1, time_2: like Current): BOOLEAN
|
||||
-- Is current between the two times?
|
||||
require
|
||||
others_exist: time_1 /= Void and time_2 /= Void
|
||||
do
|
||||
if time_1 < Current and Current < time_2 then
|
||||
Result := True
|
||||
elseif time_2 < Current and Current < time_1 then
|
||||
Result := True
|
||||
end
|
||||
ensure
|
||||
valid_result: Result implies ((time_1 < Current and Current < time_2) or else
|
||||
(time_2 < Current and Current < time_1))
|
||||
end
|
||||
|
||||
is_between_inclusive (time_1, time_2: like Current): BOOLEAN
|
||||
-- Is current between the two times or equal to one of the two times?
|
||||
require
|
||||
others_exist: time_1 /= Void and time_2 /= Void
|
||||
do
|
||||
if time_1 <= Current and Current <= time_2 then
|
||||
Result := True
|
||||
elseif time_2 <= Current and Current <= time_1 then
|
||||
Result := True
|
||||
end
|
||||
ensure
|
||||
valid_result: Result implies ((time_1 <= Current and Current <= time_2) or else
|
||||
(time_2 <= Current and Current <= time_1))
|
||||
end
|
||||
|
||||
percent_of (a_interval: like interval_anchor): DOUBLE
|
||||
-- Where does this time fall in relation to the interval?
|
||||
-- If current time is before the interval then result should be negative.
|
||||
-- If current time is after the interval then result should be > 1 (i.e. > 100%).
|
||||
-- If current time belongs to the interval then result should be between 0 and 1.
|
||||
require
|
||||
interval_exists: a_interval /= Void
|
||||
local
|
||||
int: like Interval_anchor
|
||||
do
|
||||
-- int := twin (a_interval)
|
||||
int := a_interval.deep_twin
|
||||
if is_before (a_interval) then
|
||||
int.set_start_finish (Current, a_interval.start)
|
||||
if not a_interval.duration.is_zero then
|
||||
Result := -(int.duration.percent_of (a_interval.duration))
|
||||
end
|
||||
else
|
||||
int.set_start_finish (a_interval.start, Current)
|
||||
if not a_interval.duration.is_zero then
|
||||
Result := int.duration.percent_of (a_interval.duration)
|
||||
end
|
||||
end
|
||||
ensure
|
||||
negative_if_before: Result < 0 implies Current.is_before (a_interval)
|
||||
zero_to_one_if_belongs: (Result >= 0 and Result <= 1) implies Current.belongs (a_interval)
|
||||
over_one_if_after: Result > 1 implies Current.is_after (a_interval)
|
||||
end
|
||||
|
||||
time_between (other: like Current): like duration_anchor
|
||||
-- The duration of time between Current and other
|
||||
require
|
||||
other_exists: other /= Void
|
||||
deferred
|
||||
end
|
||||
|
||||
is_valid_string_representation (a_string: STRING): BOOLEAN
|
||||
-- Is `a_string' in a format that can be used to initialize Current?
|
||||
deferred
|
||||
end
|
||||
|
||||
is_valid_integer_representation (a_integer: INTEGER): BOOLEAN
|
||||
-- Is `a_integer' in the range reconizable by Current?
|
||||
deferred
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
C_date: C_DATE
|
||||
-- Used to set the date and time based on system clock.
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
is_valid: BOOLEAN
|
||||
-- Test used by invariant.
|
||||
do
|
||||
Result := True
|
||||
end
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
duration_anchor: ABSTRACT_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
require
|
||||
not_callable: False
|
||||
do
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
interval_anchor: ABSTRACT_INTERVAL
|
||||
-- Anchor for features using intervals.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
require
|
||||
not_callable: False
|
||||
do
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
always_valid: is_valid
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2015, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
|
||||
|
||||
|
255
jj_temporal/jj_t/classes/c_date.e
Normal file
255
jj_temporal/jj_t/classes/c_date.e
Normal file
@@ -0,0 +1,255 @@
|
||||
note
|
||||
description: "Representation of a date at C level"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date: 2014-03-11 23:16:07 -0400 (Tue, 11 Mar 2014) $"
|
||||
revision: "$Revision: 35 $"
|
||||
|
||||
class
|
||||
C_DATE
|
||||
|
||||
-- This is a copy of C_DATE from ISE's time cluster. I copied
|
||||
-- it to my support cluster so I can use it in my temporal and
|
||||
-- other projects without the overhead of using all of ISE's
|
||||
-- time cluster.
|
||||
|
||||
inherit
|
||||
ANY
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create,
|
||||
make_utc
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Create an instance of C_DATA using current local time.
|
||||
do
|
||||
is_utc := False
|
||||
update
|
||||
end
|
||||
|
||||
make_utc
|
||||
-- Create an instance of C_DATE holding UTC values.
|
||||
do
|
||||
is_utc := True
|
||||
update
|
||||
ensure
|
||||
is_utc: is_utc
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
is_utc: BOOLEAN
|
||||
-- Is Current holding value in UTC format?
|
||||
|
||||
feature -- Update
|
||||
|
||||
update
|
||||
-- Pointer to `struct tm' area.
|
||||
local
|
||||
l_timeb, l_tm, l_time: POINTER
|
||||
l_milli: INTEGER
|
||||
do
|
||||
l_timeb := l_timeb.memory_alloc (timeb_structure_size)
|
||||
l_time := l_time.memory_alloc (time_t_structure_size)
|
||||
ftime (l_timeb)
|
||||
get_time (l_timeb, l_time)
|
||||
if is_utc then
|
||||
l_tm := gmtime (l_time)
|
||||
else
|
||||
l_tm := localtime (l_time)
|
||||
end
|
||||
create internal_item.make_from_pointer (l_tm, tm_structure_size)
|
||||
|
||||
l_milli := get_millitm (l_timeb)
|
||||
if l_milli < 0 or l_milli > 999 then
|
||||
millisecond_now := 0
|
||||
else
|
||||
millisecond_now := l_milli
|
||||
end
|
||||
|
||||
l_timeb.memory_free
|
||||
l_time.memory_free
|
||||
end
|
||||
|
||||
feature -- Status
|
||||
|
||||
year_now: INTEGER
|
||||
-- Current year at creation time or after last call to `update'.
|
||||
do
|
||||
Result := 1900 + get_tm_year (internal_item.item)
|
||||
ensure
|
||||
year_valid: Result >= 1900
|
||||
end
|
||||
|
||||
month_now: INTEGER
|
||||
-- Current month at creation time or after last call to `update'.
|
||||
do
|
||||
Result := get_tm_mon (internal_item.item) + 1
|
||||
ensure
|
||||
month_valid: Result >= 1 and Result <= 12
|
||||
end
|
||||
|
||||
day_now: INTEGER
|
||||
-- Current day at creation time or after last call to `update'.
|
||||
do
|
||||
Result := get_tm_mday (internal_item.item)
|
||||
ensure
|
||||
day_valid: Result >= 1 and Result <= 31
|
||||
end
|
||||
|
||||
hour_now: INTEGER
|
||||
-- Current hour at creation time or after last call to `update'.
|
||||
do
|
||||
Result := get_tm_hour (internal_item.item)
|
||||
ensure
|
||||
hour_valid: Result >= 0 and Result <= 23
|
||||
end
|
||||
|
||||
minute_now: INTEGER
|
||||
-- Current minute at creation time or after last call to `update'.
|
||||
do
|
||||
Result := get_tm_min (internal_item.item)
|
||||
ensure
|
||||
minute_valid: Result >= 0 and Result <= 59
|
||||
end
|
||||
|
||||
second_now: INTEGER
|
||||
-- Current second at creation time or after last call to `update'.
|
||||
do
|
||||
Result := get_tm_sec (internal_item.item)
|
||||
if Result > 59 then
|
||||
-- Some platform returns up to 61 for leap seconds.
|
||||
Result := 59
|
||||
end
|
||||
ensure
|
||||
second_valid: Result >= 0 and Result <= 59
|
||||
end
|
||||
|
||||
millisecond_now: INTEGER
|
||||
-- Current millisecond at creation time or after last call to `update'.
|
||||
|
||||
feature {NONE} -- Externals
|
||||
|
||||
ftime (p: POINTER)
|
||||
-- Set current date and time in `p', pointer to a `struct timeb' area.
|
||||
external
|
||||
"C macro signature (struct timeb*) use <sys/timeb.h>"
|
||||
end
|
||||
|
||||
feature {NONE} -- `struct timeb' encapsulation
|
||||
|
||||
timeb_structure_size: INTEGER
|
||||
-- Size of `struct timeb'.
|
||||
external
|
||||
"C macro use <sys/timeb.h>"
|
||||
alias
|
||||
"sizeof(struct timeb)"
|
||||
end
|
||||
|
||||
time_t_structure_size: INTEGER
|
||||
-- Size of `struct timeb'.
|
||||
external
|
||||
"C macro use <time.h>"
|
||||
alias
|
||||
"sizeof(time_t)"
|
||||
end
|
||||
|
||||
tm_structure_size: INTEGER
|
||||
-- Size of `struct tm'.
|
||||
external
|
||||
"C macro use <time.h>"
|
||||
alias
|
||||
"sizeof(struct tm)"
|
||||
end
|
||||
|
||||
get_millitm (p: POINTER): INTEGER
|
||||
-- Get `p->millitm'.
|
||||
external
|
||||
"C struct struct timeb access millitm use <sys/timeb.h>"
|
||||
end
|
||||
|
||||
get_time (p, t: POINTER)
|
||||
-- Get `p->time'.
|
||||
external
|
||||
"C inline use <sys/timeb.h>, <time.h>"
|
||||
alias
|
||||
"*(time_t *) $t = (((struct timeb *)$p)->time);"
|
||||
end
|
||||
|
||||
feature {NONE} -- `struct tm' encapsulation
|
||||
|
||||
internal_item: MANAGED_POINTER
|
||||
-- Pointer to `struct tm' area.
|
||||
|
||||
localtime (t: POINTER): POINTER
|
||||
-- Pointer to `struct tm' area.
|
||||
external
|
||||
"C inline use <time.h>"
|
||||
alias
|
||||
"localtime ((time_t *) $t)"
|
||||
end
|
||||
|
||||
gmtime (t: POINTER): POINTER
|
||||
-- Pointer to `struct tm' area in UTC.
|
||||
external
|
||||
"C inline use <time.h>"
|
||||
alias
|
||||
"gmtime ((time_t *) $t)"
|
||||
end
|
||||
|
||||
get_tm_year (p: POINTER): INTEGER
|
||||
-- Get `p->tm_year', number of years since 1900.
|
||||
external
|
||||
"C struct struct tm access tm_year use <time.h>"
|
||||
end
|
||||
|
||||
get_tm_mon (p: POINTER): INTEGER
|
||||
-- Get `p->tm_mon'.
|
||||
external
|
||||
"C struct struct tm access tm_mon use <time.h>"
|
||||
end
|
||||
|
||||
get_tm_mday (p: POINTER): INTEGER
|
||||
-- Get `p->tm_mday'.
|
||||
external
|
||||
"C struct struct tm access tm_mday use <time.h>"
|
||||
end
|
||||
|
||||
get_tm_hour (p: POINTER): INTEGER
|
||||
-- Get `p->tm_hour'.
|
||||
external
|
||||
"C struct struct tm access tm_hour use <time.h>"
|
||||
end
|
||||
|
||||
get_tm_min (p: POINTER): INTEGER
|
||||
-- Get `p->tm_min'.
|
||||
external
|
||||
"C struct struct tm access tm_min use <time.h>"
|
||||
end
|
||||
|
||||
get_tm_sec (p: POINTER): INTEGER
|
||||
-- Get `p->tm_sec'.
|
||||
external
|
||||
"C struct struct tm access tm_sec use <time.h>"
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2006, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
356 Storke Road, Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
|
||||
|
||||
|
||||
|
||||
end -- class C_DATE
|
34
jj_temporal/jj_t/classes/hms_constants.e
Normal file
34
jj_temporal/jj_t/classes/hms_constants.e
Normal file
@@ -0,0 +1,34 @@
|
||||
note
|
||||
description: "[
|
||||
Constants for use with HMS_TIME, HMS_DURATION, and HMS_INTERVAL.
|
||||
]"
|
||||
date: "24 Aug 04"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
|
||||
class
|
||||
HMS_CONSTANTS
|
||||
|
||||
feature -- Access
|
||||
|
||||
One_second: HMS_DURATION
|
||||
once
|
||||
create Result.set (0, 0, 1)
|
||||
end
|
||||
|
||||
One_minute: HMS_DURATION
|
||||
once
|
||||
create Result.set (0, 1, 0)
|
||||
end
|
||||
|
||||
One_hour: HMS_DURATION
|
||||
once
|
||||
create Result.set (1, 0, 0)
|
||||
end
|
||||
|
||||
end -- class HMS_CONSTANTS
|
281
jj_temporal/jj_t/classes/hms_duration.e
Normal file
281
jj_temporal/jj_t/classes/hms_duration.e
Normal file
@@ -0,0 +1,281 @@
|
||||
note
|
||||
description: "[
|
||||
A duration of time represented by hours, minutes, and seconds.
|
||||
]"
|
||||
names: "duration, time_duration"
|
||||
date: "1999/01/01"; updated: "14 Aug 04"
|
||||
date: "1 Jan 99"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
HMS_DURATION
|
||||
|
||||
inherit
|
||||
|
||||
ABSTRACT_DURATION
|
||||
|
||||
create
|
||||
default_create,
|
||||
set,
|
||||
set_fine
|
||||
|
||||
feature -- Access
|
||||
|
||||
as_string: STRING_8
|
||||
-- The time represented as a string.
|
||||
do
|
||||
Result := hours.out + ":" + minutes.out + ":" + seconds.out + "." + milliseconds.out
|
||||
end
|
||||
|
||||
hours: INTEGER
|
||||
-- The number of hours in this DURATION
|
||||
|
||||
minutes: INTEGER
|
||||
-- The number of minutes in this DURATION
|
||||
|
||||
seconds: INTEGER
|
||||
-- The number of seconds in this DURATION
|
||||
|
||||
milliseconds: INTEGER
|
||||
-- The number of milli-seconds in this DURATION
|
||||
|
||||
as_hours: DOUBLE
|
||||
-- Length of this duration in hours.
|
||||
do
|
||||
Result := hours + minutes / 60 + seconds / 3600 + milliseconds / 3600000
|
||||
end
|
||||
|
||||
as_minutes: DOUBLE
|
||||
-- Length of this duration in minutes.
|
||||
do
|
||||
Result := hours * 60 + minutes + seconds / 60 + milliseconds / 60000
|
||||
end
|
||||
|
||||
as_seconds: DOUBLE
|
||||
-- Length of this duration in seconds.
|
||||
do
|
||||
Result := hours * 3600 + minutes * 60 + seconds + milliseconds / 1000
|
||||
end
|
||||
|
||||
as_milliseconds: DOUBLE
|
||||
-- Length of this duration in milliseconds
|
||||
do
|
||||
Result := hours * 3600000 + minutes * 60000 + seconds * 1000 + milliseconds
|
||||
end
|
||||
|
||||
one: like Current
|
||||
-- Neutral element for '*' and '/'.
|
||||
do
|
||||
create Result.set_fine (1, 1, 1, 1)
|
||||
ensure then
|
||||
result_hours_is_one: Result.hours = 1
|
||||
result_minutes_is_one: Result.minutes = 1
|
||||
result_seconds_is_one: Result.seconds = 1
|
||||
result_millisecons_is_one: Result.milliseconds = 1
|
||||
end
|
||||
|
||||
zero: like Current
|
||||
-- Neutral element for '+' and '-'.
|
||||
do
|
||||
create Result
|
||||
ensure then
|
||||
result_hours_is_zero: Result.hours = 0
|
||||
result_minutes_is_zero: Result.minutes = 0
|
||||
result_seconds_is_zero: Result.seconds = 0
|
||||
result_milliseconds_is_zero: Result.milliseconds = 0
|
||||
end
|
||||
|
||||
percent_of (other: like Current): DOUBLE
|
||||
-- What percent of other in length is this one?
|
||||
do
|
||||
-- Used minutes because it seemed reasonable accuracy.
|
||||
Result := as_minutes / other.as_minutes
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_zero
|
||||
-- Make current have zero length.
|
||||
do
|
||||
set_fine (0, 0, 0, 0)
|
||||
end
|
||||
|
||||
set (a_hours, a_minutes, a_seconds: INTEGER)
|
||||
-- Change the hours, minutes, and seconds to these values
|
||||
-- and set milliseconds to zero.
|
||||
do
|
||||
set_fine (a_hours, a_minutes, a_seconds, 0)
|
||||
ensure
|
||||
hours_set: hours = a_hours
|
||||
minutes_set: minutes = a_minutes
|
||||
seconds_set: seconds = a_seconds
|
||||
milliseconds_zero: milliseconds = 0
|
||||
end
|
||||
|
||||
set_fine (a_hours, a_minutes, a_seconds, a_milliseconds: INTEGER)
|
||||
-- Change `hours', `minutes', `seconds', and `milliseconds'
|
||||
do
|
||||
hours := a_hours
|
||||
minutes := a_minutes
|
||||
seconds := a_seconds
|
||||
milliseconds := a_milliseconds
|
||||
ensure
|
||||
hours_set: hours = a_hours
|
||||
minutes_set: minutes = a_minutes
|
||||
seconds_set: seconds = a_seconds
|
||||
milliseconds_set: milliseconds = a_milliseconds
|
||||
end
|
||||
|
||||
set_hours (a_hours: INTEGER)
|
||||
-- Change hours
|
||||
do
|
||||
hours := a_hours
|
||||
ensure
|
||||
hours_set: hours = a_hours
|
||||
end
|
||||
|
||||
set_minutes (a_minutes: INTEGER)
|
||||
-- change minutes
|
||||
do
|
||||
minutes := a_minutes
|
||||
ensure
|
||||
minutes_set: minutes = a_minutes
|
||||
end
|
||||
|
||||
set_seconds (a_seconds: INTEGER)
|
||||
-- Change seconds
|
||||
do
|
||||
seconds := a_seconds
|
||||
ensure
|
||||
seconds_set: seconds = a_seconds
|
||||
end
|
||||
|
||||
negate
|
||||
-- Reverses the sign for hours, minutes, and seconds.
|
||||
do
|
||||
hours := -hours
|
||||
minutes := -minutes
|
||||
seconds := -seconds
|
||||
milliseconds := -milliseconds
|
||||
ensure then
|
||||
hours_negated: -hours = old hours
|
||||
minutes_negated: -minutes = old minutes
|
||||
seconds_negated: -seconds = old seconds
|
||||
milliseconds_negated: milliseconds = -milliseconds
|
||||
end
|
||||
|
||||
normalize
|
||||
-- Convert to standard format: "61 minutes" becomes "1 hour, 1 minute".
|
||||
do
|
||||
-- Fix me !!! for negatives...
|
||||
seconds := seconds + milliseconds // 999
|
||||
milliseconds := milliseconds \\ 999
|
||||
minutes := minutes + seconds // 60
|
||||
seconds := seconds \\ 60
|
||||
hours := hours + minutes // 60
|
||||
minutes := minutes \\ 60
|
||||
end
|
||||
|
||||
add (other: like Current)
|
||||
-- Add 'other'. Does not 'normalize'.
|
||||
do
|
||||
hours := hours + other.hours
|
||||
minutes := minutes + other.minutes
|
||||
seconds := seconds + other.seconds
|
||||
milliseconds := milliseconds + other.milliseconds
|
||||
ensure then
|
||||
hours_added: hours = old hours + other.hours
|
||||
minutes_added: minutes = old minutes + other.minutes
|
||||
seconds_added: seconds = old seconds + other.seconds
|
||||
milliseconds_added: milliseconds = old milliseconds + other.milliseconds
|
||||
end
|
||||
|
||||
sub (other: like Current)
|
||||
-- Subtract 'other'. Does not 'normalize'.
|
||||
do
|
||||
hours := hours - other.hours
|
||||
minutes := minutes - other.minutes
|
||||
seconds := seconds - other.seconds
|
||||
milliseconds := milliseconds - other.milliseconds
|
||||
ensure then
|
||||
hours_subbed: hours = old hours - other.hours
|
||||
minutes_subbed: minutes = old minutes - other.minutes
|
||||
seconds_subbed: seconds = old seconds - other.seconds
|
||||
milliseconds_subbed: milliseconds = old milliseconds - other.milliseconds
|
||||
end
|
||||
|
||||
multiply (r: DOUBLE)
|
||||
-- Multiply by a factor of 'r'.
|
||||
-- Result is normalized.
|
||||
local
|
||||
v: DOUBLE
|
||||
fract: DOUBLE
|
||||
do
|
||||
-- Multiply `hours'
|
||||
v := hours * r
|
||||
hours := v.floor
|
||||
fract := v - hours
|
||||
-- Multiply `minutes' and add fractional of hour
|
||||
v := minutes * r + 60 * fract
|
||||
minutes := v.floor
|
||||
fract := v - minutes
|
||||
-- Mulitply `seconds' and add fractional minute
|
||||
v := seconds * r + 60 * fract
|
||||
seconds := v.floor
|
||||
fract := v - seconds
|
||||
-- Multiply `milliseconds' and add fractional second
|
||||
v := milliseconds * r + 1000 * fract
|
||||
milliseconds := v.rounded
|
||||
-- Normalize
|
||||
normalize
|
||||
end
|
||||
|
||||
divide (r: DOUBLE)
|
||||
-- Divide by 'r'.
|
||||
-- Result is normalized.
|
||||
do
|
||||
set_fine (0, 0, 0, (as_milliseconds / r).rounded)
|
||||
normalize
|
||||
end
|
||||
|
||||
div (i: INTEGER)
|
||||
-- Integer division.
|
||||
-- Result is normalized.
|
||||
do
|
||||
set (0, 0, as_seconds.truncated_to_integer // i)
|
||||
normalize
|
||||
end
|
||||
|
||||
mod (i: INTEGER)
|
||||
-- Modulo.
|
||||
-- Result is normalized.
|
||||
do
|
||||
set (0, 0, as_seconds.truncated_to_integer \\ i)
|
||||
normalize
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
-- Is 'Current' less than 'other'?
|
||||
local
|
||||
temp, temp_other: like Current
|
||||
do
|
||||
temp := twin
|
||||
temp_other := other.twin
|
||||
temp.normalize
|
||||
temp_other.normalize
|
||||
Result := (temp.hours < temp_other.hours) or
|
||||
(temp.hours = temp_other.hours and temp.minutes < temp_other.minutes) or
|
||||
(temp.hours = temp_other.hours and temp.minutes = temp_other.minutes and temp.seconds < temp_other.seconds)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
68
jj_temporal/jj_t/classes/hms_interval.e
Normal file
68
jj_temporal/jj_t/classes/hms_interval.e
Normal file
@@ -0,0 +1,68 @@
|
||||
note
|
||||
description: "[
|
||||
A span of time consisting of a start-time, finish-time
|
||||
and duration described in terms of hours, minutes, and
|
||||
seconds. Positive durations only.
|
||||
]"
|
||||
names: "hms_interval, interval, time_span, time_interval, span"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
HMS_INTERVAL
|
||||
|
||||
inherit
|
||||
|
||||
ABSTRACT_INTERVAL
|
||||
redefine
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Create an instance starting and ending at the default creation
|
||||
-- value for the type of `start' time, having zero length duration.
|
||||
do
|
||||
-- Can't define `default_create' in ABSTRACT_INTERVAL because there
|
||||
-- `start_imp' is deffered and cannot call create on a deferred type.
|
||||
create start_imp
|
||||
finish_imp := start_imp.twin
|
||||
ensure then
|
||||
same_start_and_finish: equal (start, finish)
|
||||
zero_duration: duration.is_zero
|
||||
end
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
time_anchor: HMS_TIME
|
||||
-- Anchor for features using times.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
duration_anchor: HMS_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
end
|
551
jj_temporal/jj_t/classes/hms_time.e
Normal file
551
jj_temporal/jj_t/classes/hms_time.e
Normal file
@@ -0,0 +1,551 @@
|
||||
note
|
||||
description: "[
|
||||
An exact point of time as on a clock. An
|
||||
Hour, Minute, Second time (ie. a time).
|
||||
]"
|
||||
names: "time"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
HMS_TIME
|
||||
|
||||
inherit
|
||||
|
||||
ABSTRACT_TIME
|
||||
rename
|
||||
as_integer as as_seconds
|
||||
redefine
|
||||
default_create,
|
||||
is_valid,
|
||||
duration_anchor,
|
||||
interval_anchor
|
||||
end
|
||||
|
||||
create
|
||||
default_create,
|
||||
set_now,
|
||||
set_now_utc,
|
||||
set_now_fine,
|
||||
set_now_utc_fine,
|
||||
set,
|
||||
set_fine,
|
||||
from_seconds,
|
||||
from_string
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Create an instance with time 00:00:00 (i.e. midnight).
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
hour: INTEGER
|
||||
-- Hour part of time.
|
||||
|
||||
minute: INTEGER
|
||||
-- Minute part of time.
|
||||
|
||||
second: INTEGER
|
||||
-- Second part of time.
|
||||
|
||||
millisecond: INTEGER
|
||||
-- Millisecond part of the time.
|
||||
|
||||
overflow: INTEGER
|
||||
-- Number of days after a normalize (49 hours gives 2 days overflow).
|
||||
|
||||
as_string: STRING
|
||||
-- The time represented as a string with no seperator characters, such
|
||||
-- as ":", "-", or "/". The time 23:59:59.999 becomes "235959.999"
|
||||
do
|
||||
create Result.make (10)
|
||||
if not (hour >= 10) then
|
||||
Result.append ("0")
|
||||
end
|
||||
Result.append (hour.out)
|
||||
if not (minute >= 10) then
|
||||
Result.append ("0")
|
||||
end
|
||||
Result.append (minute.out)
|
||||
if not (second >= 10) then
|
||||
Result.append ("0")
|
||||
end
|
||||
Result.append (second.out)
|
||||
Result.append (".")
|
||||
if not (millisecond >= 100) then
|
||||
Result.append ("0")
|
||||
end
|
||||
if not (millisecond >= 10) then
|
||||
Result.append ("0")
|
||||
end
|
||||
Result.append (millisecond.out)
|
||||
end
|
||||
|
||||
as_seconds: INTEGER
|
||||
-- The number of seconds from midnight to the current time.
|
||||
-- `Millisecond' is rounded.
|
||||
do
|
||||
Result := hour * 60 * 60 + minute * 60 + second + (millisecond / 1000).rounded
|
||||
end
|
||||
|
||||
feature -- Element Change
|
||||
|
||||
from_string (a_string: STRING)
|
||||
-- Change Current to the time represented by `a_string'.
|
||||
-- It must be in the format as provided by `as_string'.
|
||||
local
|
||||
h, m, s, mil: INTEGER
|
||||
do
|
||||
h := a_string.substring (1, 2).to_integer
|
||||
m := a_string.substring (3, 4).to_integer
|
||||
s := a_string.substring (5, 6).to_integer
|
||||
mil := a_string.substring (8, 10).to_integer
|
||||
set_fine (h, m, s, mil)
|
||||
end
|
||||
|
||||
from_seconds (a_seconds: INTEGER)
|
||||
-- Initialize as `a_seconds' from midnight.
|
||||
do
|
||||
set (0, 0, 0)
|
||||
add_seconds (a_seconds)
|
||||
end
|
||||
|
||||
set_now
|
||||
-- Set current time according to timezone, setting `millisecond' to zero.
|
||||
-- This was copied from ISE's TIME class with minor changes.
|
||||
do
|
||||
C_date.update
|
||||
set_fine (C_date.hour_now, C_date.minute_now, C_date.second_now, 0)
|
||||
end
|
||||
|
||||
set_now_fine
|
||||
-- Set current time according to timezone, including milli-seconds.
|
||||
do
|
||||
C_date.update
|
||||
set_fine (C_date.hour_now, C_date.minute_now, C_date.second_now, C_date.millisecond_now)
|
||||
end
|
||||
|
||||
set_now_utc
|
||||
-- Set the current object to today's date in utc format.
|
||||
-- The `millisecond' is set to zero.
|
||||
-- This was copied from ISE's TIME class with minor changes.
|
||||
do
|
||||
C_date.update
|
||||
set (C_date.hour_now, C_date.minute_now, C_date.second_now)
|
||||
end
|
||||
|
||||
set_now_utc_fine
|
||||
-- Set the current object to today's date in utc format, including `millisecond'.
|
||||
-- This was copied from ISE's TIME class with minor changes.
|
||||
do
|
||||
C_date.update
|
||||
set_fine (C_date.hour_now, C_date.minute_now, C_date.second_now, C_date.millisecond_now)
|
||||
end
|
||||
|
||||
set (h, m, s: INTEGER)
|
||||
-- Change the hour, minute, and second.
|
||||
-- Set `millisecond' to 0.
|
||||
require
|
||||
hour_valid: 0 <= h and h <= 23;
|
||||
minute_valid: 0 <= m and m <= 59;
|
||||
second_valid: 0 <= s and s <= 59
|
||||
do
|
||||
set_fine (h, m, s, 0)
|
||||
ensure
|
||||
hour_assigned: hour = h
|
||||
minute_assigned: minute = m
|
||||
second_assigned: second = s
|
||||
millisecond_assigned: millisecond = 0
|
||||
end
|
||||
|
||||
set_fine (h, m, s, mil: INTEGER)
|
||||
-- Change the hour, minute, and second
|
||||
require
|
||||
hour_valid: 0 <= h and h <= 23
|
||||
minute_valid: 0 <= m and m <= 59
|
||||
second_valid: 0 <= s and s <= 59
|
||||
millisecond_valid: 0 <= mil and mil <= 999999
|
||||
do
|
||||
hour := h;
|
||||
minute := m;
|
||||
second := s;
|
||||
millisecond := mil
|
||||
ensure
|
||||
hour_assigned: hour = h
|
||||
minute_assigned: minute = m
|
||||
second_assigned: second = s
|
||||
millisecond_assigned: millisecond = mil
|
||||
end
|
||||
|
||||
set_hour (a_hour: INTEGER)
|
||||
-- Change the `hour'.
|
||||
require
|
||||
hour_valid: 0 <= a_hour and a_hour <= 23;
|
||||
do
|
||||
hour := a_hour
|
||||
ensure
|
||||
hour_assigned: hour = a_hour
|
||||
end
|
||||
|
||||
set_minute (a_minute: INTEGER)
|
||||
-- Change the `minute'.
|
||||
require
|
||||
minute_valid: 0 <= a_minute and a_minute <= 59;
|
||||
do
|
||||
minute := a_minute
|
||||
ensure
|
||||
minute_assigned: minute = a_minute
|
||||
end
|
||||
|
||||
set_second (a_second: INTEGER)
|
||||
-- Change the second.
|
||||
require
|
||||
second_valid: 0 <= a_second and a_second <= 59
|
||||
do
|
||||
second := a_second
|
||||
ensure
|
||||
second_assigned: second = a_second
|
||||
end
|
||||
|
||||
set_millisecond (a_millisecond: INTEGER)
|
||||
-- Change the `millisecond'
|
||||
require
|
||||
valid_millisecond: 0 <= a_millisecond and a_millisecond <= 999
|
||||
do
|
||||
millisecond := a_millisecond
|
||||
ensure
|
||||
millisecond_assigned: millisecond = a_millisecond
|
||||
end
|
||||
|
||||
from_integer (a_integer: INTEGER)
|
||||
-- Change Current to the time represented by `a_integer'.
|
||||
-- `A_compact_time' must represent a date that is not BC.
|
||||
do
|
||||
-- Fix me !!!
|
||||
end
|
||||
|
||||
clear_overflow
|
||||
-- Remove the `overflow' condition by seting overflow to 0.
|
||||
-- (Overflows occur when `add_duration' causes the time to be past 23:59:59.999)
|
||||
do
|
||||
overflow := 0
|
||||
end
|
||||
|
||||
truncate_to_hours
|
||||
-- Reset "to the hour" (set minutes and seconds to 0).
|
||||
do
|
||||
set_fine (hour, 0, 0, 0)
|
||||
ensure
|
||||
hour_unchanged: hour = old hour
|
||||
minute_zero: minute = 0
|
||||
second_zero: second = 0
|
||||
millisecond_zero: millisecond = 0
|
||||
end
|
||||
|
||||
truncate_to_minutes
|
||||
-- Reset "to the minute" (i.e. set seconds to 0.)
|
||||
do
|
||||
set_fine (hour, minute, 0, 0)
|
||||
ensure
|
||||
hour_unchanged: hour = old hour
|
||||
minute_unchanged: minute = old minute
|
||||
second_zero: second = 0
|
||||
millisecond_zero: millisecond = 0
|
||||
end
|
||||
|
||||
truncate_to_seconds
|
||||
-- Set the `millisecond' to zero.
|
||||
-- Use when `millisecond' portion is to be ignored.
|
||||
do
|
||||
set_millisecond (0)
|
||||
ensure
|
||||
hour_unchanged: hour = old hour
|
||||
minute_unchanged: minute = old minute
|
||||
second_unchaged: second = old second
|
||||
millisecond_zero: millisecond = 0
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
-- Does this time come before 'other'?
|
||||
require else
|
||||
other_time_not_void: other /= Void
|
||||
do
|
||||
Result := hour < other.hour or else
|
||||
(hour = other.hour) and (minute < other.minute) or else
|
||||
(hour = other.hour) and (minute = other.minute) and (second < other.second) or else
|
||||
(hour = other.hour) and (minute = other.minute) and (second = other.second) and (millisecond < other.millisecond)
|
||||
ensure then
|
||||
-- definition: Result = (hour < other.hour) or else
|
||||
-- (hour = other.hour) and (minute < other.minute) or else
|
||||
-- (hour = other.hour) and (minute = other.minute) and (second < other.second) or else
|
||||
-- (hour = other.hour) and (minute = other.minute) and (second = other.second) and (millisecond < other.millisecond)
|
||||
end
|
||||
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
add_duration (a_duration: like Duration_anchor)
|
||||
-- Add a length of time (in hours, minutes, and seconds) to the time.
|
||||
do
|
||||
-- hour := hour + a_duration.hours
|
||||
-- minute := minute + a_duration.minutes
|
||||
-- second := second + a_duration.seconds
|
||||
-- millisecond := millisecond + a_duration.milliseconds
|
||||
add_milliseconds (a_duration.milliseconds)
|
||||
add_seconds (a_duration.seconds)
|
||||
add_minutes (a_duration.minutes)
|
||||
add_hours (a_duration.hours)
|
||||
end
|
||||
|
||||
add_hours (a_number: INTEGER)
|
||||
-- Add `a_number' of hours to the current time
|
||||
local
|
||||
h: INTEGER
|
||||
do
|
||||
h := a_number \\ 24
|
||||
hour := hour + h
|
||||
check
|
||||
number_now_even: (a_number - h) \\ 24 = 0
|
||||
end
|
||||
overflow := (a_number - h) // 24
|
||||
if hour < 0 then
|
||||
check
|
||||
positive_overflow: overflow >= 1
|
||||
end
|
||||
hour := hour + 24
|
||||
overflow := overflow - 1
|
||||
end
|
||||
if hour >= 24 then
|
||||
hour := hour - 24
|
||||
overflow := overflow + 1
|
||||
end
|
||||
end
|
||||
|
||||
add_minutes (a_number: INTEGER)
|
||||
-- Add `a_number' of minutes to the current time.
|
||||
local
|
||||
m: INTEGER
|
||||
do
|
||||
minute := minute + a_number
|
||||
m := minute
|
||||
minute := minute \\ 60
|
||||
if minute < 0 then
|
||||
minute := minute + 60
|
||||
add_hours (-1)
|
||||
end
|
||||
add_hours (m // 60)
|
||||
end
|
||||
|
||||
add_seconds (a_number: INTEGER)
|
||||
-- Add `a_number' of seconds to the current time.
|
||||
local
|
||||
s: INTEGER
|
||||
do
|
||||
second := second + a_number
|
||||
s := second
|
||||
second := second \\ 60
|
||||
if second < 0 then
|
||||
second := second + 60
|
||||
add_minutes (-1)
|
||||
end
|
||||
add_minutes (s // 60)
|
||||
end
|
||||
|
||||
add_milliseconds (a_number: INTEGER)
|
||||
-- Add `a_number' of milliseconds to the current time.
|
||||
local
|
||||
ms: INTEGER
|
||||
do
|
||||
millisecond := millisecond + a_number
|
||||
ms := millisecond
|
||||
millisecond := millisecond \\ 1000
|
||||
if millisecond < 0 then
|
||||
millisecond := millisecond + 1000
|
||||
add_seconds (-1)
|
||||
end
|
||||
add_seconds (ms // 1000)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_representable_as_integer: BOOLEAN
|
||||
-- Can Current be represented as an integer?
|
||||
-- Caveat: the `milliseconds' will be lost due to rounding in `as_seconds'.
|
||||
do
|
||||
Result := True
|
||||
end
|
||||
|
||||
feature -- Querry
|
||||
|
||||
time_between (other: like Current): like Duration_anchor
|
||||
-- A length of time in hours, minutes, and seconds
|
||||
-- between this time and other.
|
||||
local
|
||||
larger, smaller: like Current
|
||||
h, m, s, ms: INTEGER
|
||||
do
|
||||
larger := max (other)
|
||||
smaller := min (other)
|
||||
ms := larger.millisecond - smaller.millisecond
|
||||
h := larger.hour - smaller.hour
|
||||
m := larger.minute - smaller.minute
|
||||
s := larger.second - smaller.second
|
||||
if ms < 0 then
|
||||
ms := ms + 999
|
||||
s := s - 1
|
||||
end
|
||||
if s < 0 then
|
||||
s := s + 60
|
||||
m := m - 1
|
||||
end
|
||||
if m < 0 then
|
||||
m := m + 60
|
||||
h := h - 1
|
||||
end
|
||||
create Result.set_fine (h, m, s, ms)
|
||||
if Current < other then
|
||||
Result.negate
|
||||
end
|
||||
end
|
||||
|
||||
seconds_between (a_other: like Current): INTEGER
|
||||
-- The number of seconds between Current and `other'
|
||||
require
|
||||
other_exists: a_other /= Void
|
||||
local
|
||||
larger, smaller: like Current
|
||||
h, m, s, ms: INTEGER
|
||||
do
|
||||
larger := max (a_other)
|
||||
smaller := min (a_other)
|
||||
ms := larger.millisecond - smaller.millisecond
|
||||
h := larger.hour - smaller.hour
|
||||
m := larger.minute - smaller.minute
|
||||
s := larger.second - smaller.second
|
||||
if ms < 0 then
|
||||
ms := ms + 999
|
||||
s := s - 1
|
||||
end
|
||||
if s < 0 then
|
||||
s := s + 60
|
||||
m := m - 1
|
||||
end
|
||||
if m < 0 then
|
||||
m := m + 60
|
||||
h := h - 1
|
||||
end
|
||||
Result := h * 60 * 60 + m * 60 + s
|
||||
end
|
||||
|
||||
is_valid_string_representation (a_string: STRING): BOOLEAN
|
||||
-- Is `a_string' in a format that can be used to initialize Current?
|
||||
local
|
||||
hs, ms, ss, mils: STRING
|
||||
h, m, s, mil: INTEGER
|
||||
do
|
||||
if a_string /= Void and then a_string.count = 10 and then equal (a_string.substring (7, 7), ".") then
|
||||
hs := a_string.substring (1, 2)
|
||||
ms := a_string.substring (3, 4)
|
||||
ss := a_string.substring (5, 6)
|
||||
mils := a_string.substring (8, 10)
|
||||
if hs.is_integer and then ms.is_integer and then ss.is_integer and then mils.is_integer then
|
||||
h := hs.to_integer
|
||||
m := ms.to_integer
|
||||
s := ms.to_integer
|
||||
mil := mils.to_integer
|
||||
if (h >= 0 and h <= 23) and then
|
||||
(m >= 0 and m <= 59) and then
|
||||
(s >= 0 and s <= 59) and then
|
||||
(mil >= 0 and mil <= 999) then
|
||||
Result := True
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_valid_integer_representation (a_integer: INTEGER): BOOLEAN
|
||||
-- Is `a_integer' in range to be converted to a time?
|
||||
do
|
||||
Result := a_integer >= 0
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
-- normalize is
|
||||
-- -- convert to a normal time (1 minute, 60 seconds becomes 2 minutes 0 seconds)
|
||||
-- do
|
||||
-- second := second + millisecond // 999
|
||||
-- millisecond := millisecond \\ 999
|
||||
-- if millisecond < 0 then
|
||||
-- millisecond := millisecond + 999
|
||||
-- second := second - 1
|
||||
-- end
|
||||
-- minute := minute + second // 60
|
||||
-- second := second \\ 60
|
||||
-- if second < 0 then
|
||||
-- second := second + 60
|
||||
-- minute := minute - 1
|
||||
-- end
|
||||
-- hour := hour + minute // 60
|
||||
-- minute := minute \\ 60
|
||||
-- if minute < 0 then
|
||||
-- minute := minute + 60
|
||||
-- hour := hour - 1
|
||||
-- end
|
||||
-- overflow := hour // 24
|
||||
-- hour := hour \\ 24
|
||||
-- if hour < 0 then
|
||||
-- hour := hour + 24
|
||||
-- overflow := overflow - 1
|
||||
-- end
|
||||
-- end
|
||||
|
||||
is_valid: BOOLEAN
|
||||
-- Is time in correct format?
|
||||
do
|
||||
Result := (0 <= millisecond and millisecond <= 999) and
|
||||
(0 <= second and second <= 59) and
|
||||
(0 <= minute and minute <= 59) and
|
||||
(0 <= hour and hour <= 23)
|
||||
ensure then
|
||||
valid_result: Result implies
|
||||
(0 <= millisecond and millisecond <= 999) and
|
||||
(0 <= second and second <= 59) and
|
||||
(0 <= minute and minute <= 59) and
|
||||
(0 <= hour and hour <= 23)
|
||||
end
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
duration_anchor: HMS_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
interval_anchor: HMS_INTERVAL
|
||||
-- Anchor for features using intervals.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
end
|
74
jj_temporal/jj_t/classes/hms_timer.e
Normal file
74
jj_temporal/jj_t/classes/hms_timer.e
Normal file
@@ -0,0 +1,74 @@
|
||||
note
|
||||
description: "[
|
||||
Timer for hours, minutes, seconds, and miliseconds.
|
||||
]"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
HMS_TIMER
|
||||
|
||||
inherit
|
||||
|
||||
HMS_INTERVAL
|
||||
undefine
|
||||
duration,
|
||||
out
|
||||
redefine
|
||||
default_create,
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
TIMER
|
||||
undefine
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Set up the timer
|
||||
do
|
||||
Precursor {HMS_INTERVAL}
|
||||
Precursor {TIMER}
|
||||
create cumulative
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
time_anchor: HMS_TIME
|
||||
-- Anchor for features using times.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
duration_anchor: HMS_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
60
jj_temporal/jj_t/classes/time_stampable.e
Normal file
60
jj_temporal/jj_t/classes/time_stampable.e
Normal file
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description: "[
|
||||
Objects which record their creation time.
|
||||
]"
|
||||
date: "1 Sep 04"
|
||||
date: "1 Jan 99"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
TIME_STAMPABLE
|
||||
|
||||
inherit
|
||||
|
||||
ANY
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
create timestamp.set_now_utc_fine
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
id: STRING
|
||||
-- Unique (hopefully) object id based on the creation time of the object.
|
||||
-- Concatination of Current's `generating_type' and `time_stamp'.
|
||||
do
|
||||
Result := generating_type.name.to_string_8 + " " + timestamp.as_string
|
||||
end
|
||||
|
||||
timestamp: YMDHMS_TIME
|
||||
-- Time this object was created
|
||||
|
||||
--feature -- Comparison
|
||||
|
||||
-- infix "<" (a_other: like Current): BOOLEAN is
|
||||
-- -- Is Current less than `a_other'?
|
||||
-- do
|
||||
-- Result := id < a_other.id
|
||||
---- Result := timestamp < a_other.timestamp
|
||||
-- end
|
||||
|
||||
invariant
|
||||
|
||||
time_stamp_exists: timestamp /= Void
|
||||
|
||||
end
|
122
jj_temporal/jj_t/classes/timer.e
Normal file
122
jj_temporal/jj_t/classes/timer.e
Normal file
@@ -0,0 +1,122 @@
|
||||
note
|
||||
description: "[
|
||||
Stop-watch type object.
|
||||
Create the object and call `reset' to use.
|
||||
]"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
deferred class
|
||||
TIMER
|
||||
|
||||
inherit
|
||||
|
||||
ABSTRACT_INTERVAL
|
||||
redefine
|
||||
duration
|
||||
end
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Initialize Current
|
||||
do
|
||||
create lap_times.make (10)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
duration: like duration_anchor
|
||||
-- The time between the `start' and the `finish';
|
||||
-- or the time between the `start' and the current time if
|
||||
-- the timer is running.
|
||||
local
|
||||
t: like time_anchor
|
||||
do
|
||||
if is_running then
|
||||
t := finish
|
||||
t.set_now_utc_fine
|
||||
Result := t.time_between (start)
|
||||
else
|
||||
Result := Precursor
|
||||
end
|
||||
end
|
||||
|
||||
cumulative: like duration_anchor
|
||||
-- Cumulative total of all the times elapsed on the timer.
|
||||
-- Recalculated at every `stop'.
|
||||
|
||||
i_th_lap (a_index: INTEGER): like duration_anchor
|
||||
-- The `a_index'th duration.
|
||||
require
|
||||
is_valid_lap_index: is_valid_lap_index (a_index)
|
||||
do
|
||||
Result := lap_times.i_th (a_index)
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_running: BOOLEAN
|
||||
-- Is the timer running?
|
||||
-- (Use `start' to begin timing and `stop' to end.)
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
reset
|
||||
-- Reset `elapsed' to zero.
|
||||
do
|
||||
start_imp.set_now_utc_fine
|
||||
finish_imp.copy (start)
|
||||
cumulative.set_zero
|
||||
lap_times.wipe_out
|
||||
end
|
||||
|
||||
run
|
||||
-- Start the timer
|
||||
require
|
||||
not_running: not is_running
|
||||
do
|
||||
is_running := True
|
||||
start_imp.set_now_utc_fine
|
||||
ensure
|
||||
is_running: is_running
|
||||
end
|
||||
|
||||
stop
|
||||
-- Stop the timer
|
||||
require
|
||||
is_running: is_running
|
||||
do
|
||||
is_running := False
|
||||
finish_imp.set_now_utc_fine
|
||||
cumulative := cumulative + duration
|
||||
-- start_imp.copy (finish)
|
||||
-- mark_lap
|
||||
ensure
|
||||
is_stopped: not is_running
|
||||
end
|
||||
|
||||
mark_lap
|
||||
-- Record the current `lap' time in `lap_times' but keep the timer running.
|
||||
do
|
||||
lap_times.extend (duration)
|
||||
end
|
||||
|
||||
feature -- Querry
|
||||
|
||||
is_valid_lap_index (a_index: INTEGER): BOOLEAN
|
||||
-- Is `a_index' a valid value into the list of `lap_times'?
|
||||
do
|
||||
Result := lap_times.valid_index (a_index)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
lap_times: ARRAYED_LIST [like duration_anchor]
|
||||
-- List of durations for each time `mark_lap' was called.
|
||||
|
||||
end
|
48
jj_temporal/jj_t/classes/ymd_constants.e
Normal file
48
jj_temporal/jj_t/classes/ymd_constants.e
Normal file
@@ -0,0 +1,48 @@
|
||||
note
|
||||
description: "[
|
||||
Constants for use with YMD_TIME, YMD_DURATION, and YMD_INTERVAL.
|
||||
]"
|
||||
date: "1 Jan 99"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMD_CONSTANTS
|
||||
|
||||
feature -- Access
|
||||
|
||||
One_day: YMD_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 0, 1)
|
||||
end
|
||||
|
||||
One_week: YMD_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 0, 7)
|
||||
end
|
||||
|
||||
One_month: YMD_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 1, 0)
|
||||
end
|
||||
|
||||
One_quarter: YMD_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 3, 0)
|
||||
end
|
||||
|
||||
One_year: YMD_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (1, 0, 0)
|
||||
end
|
||||
|
||||
end -- class YMD_CONSTANTS
|
325
jj_temporal/jj_t/classes/ymd_duration.e
Normal file
325
jj_temporal/jj_t/classes/ymd_duration.e
Normal file
@@ -0,0 +1,325 @@
|
||||
note
|
||||
description: "[
|
||||
Duration of time described in years, months, and days.
|
||||
]"
|
||||
names: "ymd_duration"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMD_DURATION
|
||||
|
||||
inherit
|
||||
|
||||
ABSTRACT_DURATION
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Create an instance with zero length.
|
||||
do
|
||||
days_per_month := default_days_per_month
|
||||
set (0, 0, 0)
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
as_string: STRING_8
|
||||
-- The time represented as a string.
|
||||
do
|
||||
Result := years.out + ":" + months.out + ":" + days.out
|
||||
end
|
||||
|
||||
years: INTEGER
|
||||
-- Number of years part.
|
||||
-- Does not consider the months or days.
|
||||
|
||||
months: INTEGER
|
||||
-- Number of months part.
|
||||
-- Does not consider the years or days.
|
||||
|
||||
days: INTEGER
|
||||
-- Number of days part.
|
||||
-- Does not consider the months or years.
|
||||
|
||||
default_days_per_month: DOUBLE = 30.4375
|
||||
-- Default value for 'days_per_month'.
|
||||
-- 365.25 days per year divided by 12 months per year.
|
||||
|
||||
days_per_month: DOUBLE
|
||||
-- Number of days in a month. (28?, 29?, 30?, 31?)
|
||||
-- Value assumed by class to do calculations involving conversion
|
||||
-- from days to months to years.
|
||||
-- Default = 30.4375 days / month.
|
||||
|
||||
days_per_year: DOUBLE
|
||||
-- Number of days in the year. Calculated based on 'days_per_month'.
|
||||
-- Value assumed by class to do calculations involving conversion
|
||||
-- from days to months to years.
|
||||
-- Default = 365.25 days / year.
|
||||
do
|
||||
Result := days_per_month * 12
|
||||
end
|
||||
|
||||
as_years: DOUBLE
|
||||
-- Length of duration in years.
|
||||
do
|
||||
Result := years + months / 12 + days / days_per_year
|
||||
end
|
||||
|
||||
as_months: DOUBLE
|
||||
-- Length of duration in months.
|
||||
do
|
||||
Result := years * 12 + months + days / days_per_month
|
||||
end
|
||||
|
||||
as_days: DOUBLE
|
||||
-- Length of duration in days.
|
||||
do
|
||||
Result := years * days_per_year + months * days_per_month + days
|
||||
end
|
||||
|
||||
one: like Current
|
||||
-- Neutral element for "*" and "/"
|
||||
do
|
||||
create Result
|
||||
Result.set (1,1,1)
|
||||
ensure then
|
||||
result_years_is_one: Result.years = 1
|
||||
result_months_is_one: Result.months = 1
|
||||
result_days_is_one: Result.days = 1
|
||||
end
|
||||
|
||||
zero: like Current
|
||||
-- Neutral element for "+" and "-"
|
||||
do
|
||||
create Result
|
||||
ensure then
|
||||
result_years_is_zero: Result.years = 0
|
||||
result_months_is_zero: Result.months = 0
|
||||
result_days_is_zero: Result.days = 0
|
||||
end
|
||||
|
||||
percent_of (other: like Current): DOUBLE
|
||||
-- What percent of other in length is this one?
|
||||
-- For example: is current duration at least twice as long as other?
|
||||
do
|
||||
-- Result := as_months / other.as_months -- Used months because it seemed reasonable accuracy.
|
||||
Result := as_days / other.as_days -- Must use days because of accuracy problems with month length.
|
||||
end
|
||||
|
||||
normalized: like Current
|
||||
-- A copy of Current in a normalized form.
|
||||
do
|
||||
Result := twin
|
||||
Result.normalize
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_zero
|
||||
-- Make Current have zero length.
|
||||
do
|
||||
set (0, 0, 0)
|
||||
end
|
||||
|
||||
set (ys, ms, ds: INTEGER)
|
||||
-- Change the length of years, months, and days.
|
||||
do
|
||||
years := ys
|
||||
months := ms
|
||||
days := ds
|
||||
ensure
|
||||
years_set: years = ys
|
||||
months_set: months = ms
|
||||
days_set: days = ds
|
||||
end
|
||||
|
||||
set_years (ys: INTEGER)
|
||||
-- Change years
|
||||
do
|
||||
years := ys
|
||||
ensure
|
||||
years_set: years = ys
|
||||
end
|
||||
|
||||
set_months (ms: INTEGER)
|
||||
-- Change months
|
||||
do
|
||||
months := ms;
|
||||
ensure
|
||||
months_set: months = ms
|
||||
end
|
||||
|
||||
set_days (ds: INTEGER)
|
||||
-- Change days
|
||||
do
|
||||
days := ds
|
||||
ensure
|
||||
days_set: days = ds
|
||||
end
|
||||
|
||||
set_days_per_month (i: DOUBLE)
|
||||
-- Change 'days_per_month' (value used in calculations
|
||||
-- involving month lenghts).
|
||||
require
|
||||
in_range: i >= 28 and i <= 31
|
||||
do
|
||||
days_per_month := i
|
||||
ensure
|
||||
days_per_month_set: days_per_month = i
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
negate
|
||||
-- Reverse the sign on years, months, and days.
|
||||
do
|
||||
years := -years;
|
||||
months := -months;
|
||||
days := -days
|
||||
ensure then
|
||||
years_negated: -years = old years
|
||||
months_negated: -months = old months
|
||||
days_negated: -days = old days
|
||||
end
|
||||
|
||||
normalize
|
||||
-- Convert to standard format: "13 months" becomes "1 year, 1 month".
|
||||
-- Month and year length is based on 'days_per_month'.
|
||||
-- This feature is hard to define. For example, is 28 days equal to
|
||||
-- one month? What about 30 days?
|
||||
-- This needs to be fixed.
|
||||
require
|
||||
days_per_month > 0
|
||||
local
|
||||
m, d: DOUBLE
|
||||
dpm: DOUBLE
|
||||
do
|
||||
-- The check on `days_per_month' was necessary because `<' which calls
|
||||
-- this feature must be getting called before the object is fully
|
||||
-- initialized, so at that point `days_per_month' is zero; this check
|
||||
-- prevents that "floating point exception".
|
||||
if days_per_month = 0 then
|
||||
dpm := Default_days_per_month
|
||||
else
|
||||
dpm := days_per_month
|
||||
end
|
||||
d := days
|
||||
m := d / dpm
|
||||
months := months + m.truncated_to_integer
|
||||
m := m - m.truncated_to_integer
|
||||
d := m * dpm
|
||||
days := d.truncated_to_integer
|
||||
-- if (d - days) > 0.5 then
|
||||
-- days := days + 1
|
||||
-- if days > dpm then
|
||||
-- months := months + 1
|
||||
-- end
|
||||
-- end
|
||||
years := years + months // 12
|
||||
months := months \\ 12
|
||||
end
|
||||
|
||||
add (other: like Current)
|
||||
-- Add other to current.
|
||||
do
|
||||
years := years + other.years;
|
||||
months := months + other.months;
|
||||
days := days + other.days
|
||||
ensure then
|
||||
years_added: years = old years + other.years
|
||||
months_added: months = old months + other.months
|
||||
days_add: days = old days + other.days
|
||||
end
|
||||
|
||||
sub (other: like Current)
|
||||
-- Subtract other from current.
|
||||
do
|
||||
years := years - other.years;
|
||||
months := months - other.months;
|
||||
days := days - other.days
|
||||
ensure then
|
||||
years_subbed: years = old years - other.years
|
||||
months_subbed: months = old months - other.months
|
||||
days_subbed: days = old days - other.days
|
||||
end
|
||||
|
||||
multiply (r: DOUBLE)
|
||||
-- Multiply by a factor of 'r'.
|
||||
-- Result is normalized.
|
||||
local
|
||||
v: DOUBLE
|
||||
fract: DOUBLE
|
||||
do
|
||||
v := years * r
|
||||
years := v.floor
|
||||
fract := v - years
|
||||
|
||||
v := months * r + 12 * fract
|
||||
months := v.floor
|
||||
fract := v - months
|
||||
|
||||
v := days * r + days_per_month * fract
|
||||
days := v.rounded
|
||||
normalize
|
||||
end
|
||||
|
||||
divide (r: DOUBLE)
|
||||
-- Divide by 'r'.
|
||||
-- Result is normalized.
|
||||
do
|
||||
set (0, 0, (as_days / r).rounded)
|
||||
normalize
|
||||
end
|
||||
|
||||
|
||||
div (i: INTEGER)
|
||||
-- Integer division.
|
||||
-- Result is normalized.
|
||||
do
|
||||
set (0, 0, (as_days / i).truncated_to_integer)
|
||||
normalize
|
||||
end
|
||||
|
||||
mod (i: INTEGER)
|
||||
-- Modulo of duration with 'i'.
|
||||
-- Result is normalized.
|
||||
do
|
||||
set (0, 0, as_days.truncated_to_integer \\ i)
|
||||
normalize
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
-- Is current shorter than other?
|
||||
local
|
||||
temp, temp_other: like Current
|
||||
do
|
||||
temp := twin
|
||||
temp_other := other.twin
|
||||
temp.normalize
|
||||
temp_other.normalize
|
||||
Result := (temp.years < temp_other.years) or else
|
||||
(temp.years = temp_other.years and temp.months < temp_other.months) or else
|
||||
(temp.years = temp_other.years and temp.months = temp_other.months and temp.days < temp_other.days)
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
days_per_month_in_range: days_per_month >= 28 and days_per_month <= 31
|
||||
|
||||
|
||||
end -- class YMD_DURATION
|
||||
|
67
jj_temporal/jj_t/classes/ymd_interval.e
Normal file
67
jj_temporal/jj_t/classes/ymd_interval.e
Normal file
@@ -0,0 +1,67 @@
|
||||
note
|
||||
description: "[
|
||||
A span of time consisting of a start-time, finish-time and duration
|
||||
described in terms of years, months, and days. Positive durations only.
|
||||
]"
|
||||
names: "ymd_interval, interval, time_span, time_interval, span"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMD_INTERVAL
|
||||
|
||||
inherit
|
||||
|
||||
ABSTRACT_INTERVAL
|
||||
redefine
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Create an instance starting and ending at the default creation
|
||||
-- value for the type of `start' time, having zero length duration.
|
||||
do
|
||||
-- Can't define `default_create' in ABSTRACT_INTERVAL because there
|
||||
-- `start_imp' is deffered and cannot call create on a deferred type.
|
||||
create start_imp
|
||||
finish_imp := start_imp.twin
|
||||
ensure then
|
||||
same_start_and_finish: equal (start, finish)
|
||||
zero_duration: duration.is_zero
|
||||
end
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
time_anchor: YMD_TIME
|
||||
-- Anchor for features using times.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
duration_anchor: YMD_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
end
|
671
jj_temporal/jj_t/classes/ymd_time.e
Normal file
671
jj_temporal/jj_t/classes/ymd_time.e
Normal file
@@ -0,0 +1,671 @@
|
||||
note
|
||||
description: "[
|
||||
An exact point of time as on a gregorian callendar.
|
||||
Has a `Year', `Month', and `Day' (i.e. a date).
|
||||
]"
|
||||
names: "date, time"
|
||||
date: "1 Jan 99"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMD_TIME
|
||||
|
||||
inherit
|
||||
|
||||
ABSTRACT_TIME
|
||||
rename
|
||||
as_integer as as_days,
|
||||
from_integer as from_days
|
||||
redefine
|
||||
default_create,
|
||||
is_valid,
|
||||
duration_anchor,
|
||||
interval_anchor
|
||||
end
|
||||
|
||||
create
|
||||
default_create,
|
||||
set_now,
|
||||
set_now_utc,
|
||||
set,
|
||||
from_days,
|
||||
from_string
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Create an instance based on todays date.
|
||||
do
|
||||
set_now
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
year: INTEGER
|
||||
-- Year part of the date.
|
||||
|
||||
month: INTEGER
|
||||
-- Month part of the date.
|
||||
|
||||
day: INTEGER
|
||||
-- Day part of the date.
|
||||
do
|
||||
Result := internal_day
|
||||
if Result > last_day_of_month then
|
||||
Result := last_day_of_month
|
||||
end
|
||||
end
|
||||
|
||||
week_number: INTEGER
|
||||
-- Week of the year containing this date.
|
||||
local
|
||||
d: YMD_TIME
|
||||
first_d: INTEGER -- Jan 1st is on what day?
|
||||
do
|
||||
create d
|
||||
d.set (year, 1, 1)
|
||||
first_d := d.weekday
|
||||
Result := (((julian + first_d - 1 - 1) // 7) + 1)
|
||||
ensure
|
||||
result_large_enough: Result >= 1
|
||||
result_small_enough: Result <= 54 -- 53 ? 54 if leapyear falls just right.
|
||||
end
|
||||
|
||||
last_day_of_month: INTEGER
|
||||
-- Date of last day for current month
|
||||
do
|
||||
inspect
|
||||
month
|
||||
when 2 then
|
||||
if is_leapyear then
|
||||
Result := 29
|
||||
else
|
||||
Result := 28
|
||||
end
|
||||
when 4, 6, 9, 11 then
|
||||
Result := 30
|
||||
else
|
||||
Result := 31
|
||||
end
|
||||
ensure
|
||||
day_in_range: Result >= 28 and Result <= 31
|
||||
good_not_leap: Result = 28 implies (month = 2 and not is_leapyear)
|
||||
good_in_leap: Result = 29 implies (month = 2 and is_leapyear)
|
||||
good_30s: Result = 30 implies (month = 4 or month = 6 or month = 9 or month = 11)
|
||||
good_31s: Result = 31 implies (month=1 or month=3 or month=5 or month=7 or month=8 or month=10 or month=12)
|
||||
end
|
||||
|
||||
days_remaining_this_month: INTEGER
|
||||
-- Number of days from current until end of month.
|
||||
-- Used in some calculations.
|
||||
do
|
||||
Result := last_day_of_month - day
|
||||
ensure
|
||||
valid_result: Result >= 0 and Result < last_day_of_month
|
||||
end
|
||||
|
||||
julian: INTEGER
|
||||
-- Day of the year between 1 and 366
|
||||
local
|
||||
n,i : INTEGER
|
||||
do
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i >= month
|
||||
loop
|
||||
inspect i
|
||||
when 2 then
|
||||
if is_leapyear then
|
||||
n := n + 29
|
||||
else
|
||||
n := n + 28
|
||||
end
|
||||
when 4,6,9,11 then
|
||||
n := n + 30
|
||||
else
|
||||
n := n + 31
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
result := n + day
|
||||
ensure
|
||||
valid_leapyear_result: is_leapyear implies (1 <= Result and Result <= 366)
|
||||
valid_result: not is_leapyear implies (1 <= Result and Result <= 365)
|
||||
end
|
||||
|
||||
|
||||
weekday: INTEGER
|
||||
-- 1 for Sunday, 2 for Monday, etc
|
||||
-- Only works as far back as ~2 Mar 0001. ???
|
||||
local
|
||||
x : INTEGER
|
||||
do
|
||||
x := internal\\7 + 1 + 1
|
||||
if x > 7 then -- it can only be 8
|
||||
x := 1
|
||||
end
|
||||
result := x
|
||||
ensure
|
||||
valid_weekday: 1 <= Result and Result <= 7
|
||||
end
|
||||
|
||||
as_string: STRING
|
||||
-- The date represented as a string with no spaces.
|
||||
-- 18 Jan 2005 would be "20050118".
|
||||
do
|
||||
create Result.make (10)
|
||||
if is_bc then
|
||||
Result.append ("BC")
|
||||
end
|
||||
if not (year.abs >= 1000) then
|
||||
Result.append ("0")
|
||||
end
|
||||
if not (year.abs >= 100) then
|
||||
Result.append ("0")
|
||||
end
|
||||
if not (year.abs >= 10) then
|
||||
Result.append ("0")
|
||||
end
|
||||
Result.append (year.abs.out)
|
||||
if not (month >= 10) then
|
||||
Result.append ("0")
|
||||
end
|
||||
Result.append (month.out)
|
||||
if not (day >= 10) then
|
||||
Result.append ("0")
|
||||
end
|
||||
Result.append (day.out)
|
||||
end
|
||||
|
||||
as_days: INTEGER
|
||||
-- The number of days from midnight (00:00:00)
|
||||
-- on 1 Jan 1970 to the beginning Current's `day'.
|
||||
local
|
||||
t: YMD_TIME
|
||||
do
|
||||
create t
|
||||
t.set (1970, 1, 1)
|
||||
Result := days_between (t)
|
||||
end
|
||||
|
||||
feature -- Element Change
|
||||
|
||||
from_days (a_days: INTEGER)
|
||||
-- Change Current to the time represented by `a_days'.
|
||||
-- `A_days' is assumed to be the number of days since 1 Jan 1970.
|
||||
-- `A_days' must represent a date that is not BC
|
||||
do
|
||||
set (1970, 1, 1)
|
||||
add_days (a_days)
|
||||
end
|
||||
|
||||
from_string (a_string: STRING)
|
||||
-- Change Current to the time represented by `a_string'.
|
||||
-- It must be in the format as provided by `as_string'.
|
||||
local
|
||||
d, m, y: INTEGER
|
||||
do
|
||||
y := a_string.substring (1, 4).to_integer
|
||||
m := a_string.substring (5, 6).to_integer
|
||||
d := a_string.substring (7, 8).to_integer
|
||||
set (y, m, d)
|
||||
end
|
||||
|
||||
set_now
|
||||
-- Set the current object to today's date.
|
||||
-- This was copied from ISE's DATE class with the one minor change.
|
||||
do
|
||||
C_date.update
|
||||
set (C_date.year_now, C_date.month_now, C_date.day_now)
|
||||
end
|
||||
|
||||
set_now_utc
|
||||
-- Set the current object to today's date in utc format.
|
||||
-- This was copied from ISE's DATE class with the one minor change.
|
||||
do
|
||||
C_date.update
|
||||
set (C_date.year_now, C_date.month_now, C_date.day_now)
|
||||
end
|
||||
|
||||
set_now_utc_fine
|
||||
-- Set the current object to today's date in utc format.
|
||||
-- This was copied from ISE's TIME class with minor changes.
|
||||
do
|
||||
C_date.update
|
||||
set (C_date.year_now, C_date.month_now, C_date.day_now)
|
||||
end
|
||||
|
||||
set (a_year, a_month, a_day: INTEGER)
|
||||
-- Give date new year, month, and day.
|
||||
-- If day > num days in month then day will return last day in the month.
|
||||
require
|
||||
realistic_year: a_year /= 0
|
||||
realistic_month: a_month >= 1 and a_month <= 12
|
||||
realistic_day: a_day >= 1 and a_day <= 31
|
||||
do
|
||||
year := a_year
|
||||
month := a_month
|
||||
internal_day := a_day
|
||||
ensure
|
||||
year_assigned: year = a_year
|
||||
month_assigned: month = a_month
|
||||
day_assigned: day = a_day
|
||||
end
|
||||
|
||||
set_year (a_year: INTEGER)
|
||||
-- Change the year.
|
||||
require
|
||||
realistic_year: a_year /= 0
|
||||
do
|
||||
year := a_year
|
||||
ensure
|
||||
year_assigned: year = a_year
|
||||
end
|
||||
|
||||
set_month (a_month: INTEGER)
|
||||
-- Change the month.
|
||||
require
|
||||
realistic_month: a_month >= 1 and a_month <= 12
|
||||
do
|
||||
month := a_month
|
||||
ensure
|
||||
month_assigned: month = a_month
|
||||
end
|
||||
|
||||
set_day (a_day: INTEGER)
|
||||
-- Change the day.
|
||||
-- If a_day > number of days in the month then
|
||||
-- 'day' will be the last day of month.
|
||||
require
|
||||
realistic_day: a_day >= 1 and a_day <= 31
|
||||
do
|
||||
internal_day := a_day
|
||||
ensure
|
||||
day_assigned: day = a_day
|
||||
end
|
||||
|
||||
truncate_to_years
|
||||
-- Set the day to first day of month 1.
|
||||
-- Use when all but the `year' is to be ignored.
|
||||
do
|
||||
set_day (1)
|
||||
set_month (1)
|
||||
ensure
|
||||
year_unchanged: year = old year
|
||||
month_one: month = 1
|
||||
day_one: day = 1
|
||||
end
|
||||
|
||||
truncate_to_months
|
||||
-- Set day to first day of current month.
|
||||
-- Use when the `day' portion of date is to be ignored.
|
||||
do
|
||||
set_day (1)
|
||||
ensure
|
||||
year_unchanged: year = old year
|
||||
month_unchanged: month = old month
|
||||
day_one: day = 1
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_leapyear: BOOLEAN
|
||||
-- Is this a leapyear?
|
||||
do
|
||||
if is_bc then
|
||||
Result := (year + 1) \\ 4 = 0 and not ((year + 1) \\ 400 = 0)
|
||||
else
|
||||
Result := year \\ 4 = 0 and (not (year \\ 100 = 0) or else year \\ 400 = 0)
|
||||
end
|
||||
end
|
||||
|
||||
is_bc: BOOLEAN
|
||||
-- Does the date represent a date B.C. (ie year < 1)
|
||||
do
|
||||
Result := year <= -1
|
||||
ensure
|
||||
definition: Result implies year <= -1
|
||||
end
|
||||
|
||||
is_representable_as_integer: BOOLEAN
|
||||
-- Can Current be represented as an integer?
|
||||
do
|
||||
Result := not is_bc and then
|
||||
(Current >= Minimum_representable_date and Current <= Maximum_representable_date)
|
||||
end
|
||||
|
||||
feature -- Querry
|
||||
|
||||
days_between (other: like Current): INTEGER
|
||||
-- Days between this date and 'other'.
|
||||
-- Only works back to ~2 Mar 0001.
|
||||
require
|
||||
other_exists : other /= Void
|
||||
do
|
||||
Result := (other.internal - internal).abs
|
||||
ensure
|
||||
definition: Result = (other.internal - internal).abs
|
||||
end
|
||||
|
||||
time_between (other: like Current): like Duration_anchor
|
||||
-- The difference between two dates as a duration
|
||||
local
|
||||
larger, smaller: like Current
|
||||
y, m, d: INTEGER
|
||||
do
|
||||
larger := max (other)
|
||||
smaller := min (other)
|
||||
y := larger.year - smaller.year
|
||||
m := larger.month - smaller.month
|
||||
d := larger.day - smaller.day
|
||||
if d < 0 then
|
||||
d := d + smaller.last_day_of_month
|
||||
m := m - 1
|
||||
end
|
||||
if m < 0 then
|
||||
m := m + 12
|
||||
y := y - 1
|
||||
end
|
||||
create Result
|
||||
Result.set (y, m, d)
|
||||
if Current < other then
|
||||
Result.negate
|
||||
end
|
||||
end
|
||||
|
||||
is_valid_integer_representation (a_integer: INTEGER): BOOLEAN
|
||||
-- Is `a_integer' in range to be converted to a time?
|
||||
-- Dependent on the `internal' representation of dates.
|
||||
do
|
||||
-- These values were found by trial and error. This will give a
|
||||
-- date from 1 Jan 0001 to 18 Oct 1,469,902, which, I believe, is
|
||||
-- far enough into the future.
|
||||
Result := a_integer >= 1721426 and a_integer <= 538592032
|
||||
ensure then
|
||||
definition: Result implies (a_integer >= 1721426) and then
|
||||
(a_integer <= 538592032) -- dependent on `internal'
|
||||
end
|
||||
|
||||
is_valid_string_representation (a_string: STRING): BOOLEAN
|
||||
-- Is `a_string' in a format that can be used to initialize Current?
|
||||
local
|
||||
bcs: detachable STRING
|
||||
ys, ms, ds: STRING
|
||||
y, m, d: INTEGER
|
||||
pad: INTEGER -- add 2 if is "BC"
|
||||
do
|
||||
if a_string /= Void and then (a_string.count = 8 or a_string.count = 10) then
|
||||
if a_string.count = 10 then
|
||||
pad := 2
|
||||
bcs := a_string.substring (1, 2)
|
||||
end
|
||||
ys := a_string.substring (1 + pad, 4 + pad)
|
||||
ms := a_string.substring (5 + pad, 6 + pad)
|
||||
ds := a_string.substring (7 + pad, 8 + pad)
|
||||
if ys.is_integer and then ms.is_integer and then ds.is_integer then
|
||||
y := ys.to_integer
|
||||
m := ms.to_integer
|
||||
d := ds.to_integer
|
||||
if (y /= 0) and then (m >= 0 and m < 12)and then (d >= 0 and d <= 31) then
|
||||
Result := True
|
||||
if bcs /= Void and then not equal (bcs, "BC") then
|
||||
Result := False
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
add_years (a_num: INTEGER)
|
||||
-- Add 'a_num' number of years to the date. Works for negative numbers also.
|
||||
local
|
||||
y: INTEGER
|
||||
do
|
||||
y := year
|
||||
year := year + a_num
|
||||
if year = 0 then -- Must preserve invarient: year can not be 0.
|
||||
if y < 0 then -- year was less than 0 and increased to 0.
|
||||
year := 1
|
||||
else -- year was greater than 0 and decreased to 0.
|
||||
year := -1
|
||||
end
|
||||
end
|
||||
ensure
|
||||
valid_date: is_valid
|
||||
end
|
||||
|
||||
add_months (a_num: INTEGER)
|
||||
-- Add 'a_num' number of months to the date. Works for negative numbers also.
|
||||
local
|
||||
m: INTEGER -- store month prior making month valid to call 'add_years'.
|
||||
do
|
||||
month := month + a_num
|
||||
m := month
|
||||
month := month \\ 12 -- preserve invarient
|
||||
if month < 1 then
|
||||
month := month + 12 -- preserve invarient
|
||||
add_years (-1)
|
||||
end
|
||||
add_years (m // 12) -- add a year for every multiple of 12.
|
||||
ensure
|
||||
valid_date: is_valid
|
||||
end
|
||||
|
||||
add_days (a_num: INTEGER)
|
||||
-- Add 'a_num' number of days to the date. Works for negative numbers also.
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
if a_num > 0 then
|
||||
from i := a_num
|
||||
until i <= days_remaining_this_month
|
||||
loop
|
||||
i := i - (days_remaining_this_month + 1)
|
||||
set_day (1)
|
||||
add_months (1)
|
||||
end
|
||||
set_day (day + i)
|
||||
elseif a_num < 0 then
|
||||
from
|
||||
i := a_num.abs
|
||||
until
|
||||
i < day
|
||||
loop
|
||||
i := (day - i).abs
|
||||
add_months (-1)
|
||||
set_day (last_day_of_month)
|
||||
end
|
||||
set_day (day - i)
|
||||
else
|
||||
-- do nothing if a_num = 0
|
||||
end
|
||||
ensure
|
||||
valid_date: is_valid
|
||||
end
|
||||
|
||||
add_duration (a_duration: like Duration_anchor)
|
||||
-- Add a length of time (in years, months, and days) to the date.
|
||||
do
|
||||
add_days (a_duration.days)
|
||||
add_months (a_duration.months)
|
||||
add_years (a_duration.years)
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
-- Does this date come before 'other'?
|
||||
require else
|
||||
other_not_void: other /= Void
|
||||
do
|
||||
Result := year < other.year or else
|
||||
(year = other.year) and (month < other.month) or else
|
||||
(year = other.year) and (month = other.month) and (day < other.day)
|
||||
ensure then
|
||||
-- definition: year < other.year or else
|
||||
-- (year = other.year) and (month < other.month) or else
|
||||
-- (year = other.year) and (month = other.month) and (day < other.day)
|
||||
end
|
||||
|
||||
feature {YMD_TIME} -- Implementation
|
||||
|
||||
frozen internal: INTEGER
|
||||
-- Internal representation of YMD_TIME
|
||||
-- Used internally by some features.
|
||||
-- Does not work for BC dates; only works back to 1 January 0001,
|
||||
-- at which time the result is 1,721,426.
|
||||
-- Will work up to a date of 18 Oct 1,469,902 (found by trial).
|
||||
require
|
||||
not_bc: not is_bc
|
||||
local
|
||||
c, ya : INTEGER;
|
||||
d,m,y : INTEGER;
|
||||
do
|
||||
d := day;
|
||||
m := month;
|
||||
y := year;
|
||||
if m > 2 then
|
||||
m := m - 3;
|
||||
else
|
||||
m := m + 9;
|
||||
y := y - 1;
|
||||
end
|
||||
c := y // 100;
|
||||
ya := y - 100 * c;
|
||||
result := (146097 * c) // 4 + (1461 * ya) // 4 + (153 * m + 2) // 5 + d + 1721119;
|
||||
ensure
|
||||
result_large_enough: Result >= 1721426
|
||||
result_small_enough: Result <= 538592032
|
||||
end
|
||||
|
||||
frozen from_internal (num: INTEGER)
|
||||
-- Create a YMD_TIME from an internal representation.
|
||||
local
|
||||
y,m,d,j : INTEGER
|
||||
do
|
||||
j := num;
|
||||
j := j - 1721119
|
||||
y := (4 * j - 1) // 146097; j := 4 * j - 1 - 146097 * y;
|
||||
d := j // 4;
|
||||
j := (4 * d + 3) // 1461; d := 4 * d + 3 - 1461 * j;
|
||||
d := (d + 4) // 4;
|
||||
m := (5 * d - 3) // 153; d := 5 * d - 3 - 153 * m;
|
||||
d := (d + 5) // 5;
|
||||
y := 100 * y + j;
|
||||
if m < 10 then
|
||||
m := m + 3;
|
||||
else
|
||||
m := m - 9;
|
||||
y := y + 1;
|
||||
end;
|
||||
internal_day := d;
|
||||
month := m;
|
||||
year := y;
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
internal_day: INTEGER
|
||||
-- Used to save last day of month if day is greater than 28, 30, or 31.
|
||||
-- Actual day is calculated from this value.
|
||||
|
||||
is_valid: BOOLEAN
|
||||
-- Is the date logical?
|
||||
do
|
||||
Result := is_valid_year and is_valid_month and is_valid_day
|
||||
end
|
||||
|
||||
is_valid_year: BOOLEAN
|
||||
-- Is the year logical?
|
||||
-- Only invalid year is year "0".
|
||||
do
|
||||
Result := year /= 0
|
||||
ensure
|
||||
definition: year /= 0
|
||||
end
|
||||
|
||||
is_valid_month: BOOLEAN
|
||||
-- Is the month logical?
|
||||
do
|
||||
Result := 1 <= month and month <= 12
|
||||
ensure
|
||||
definition: 1 <= month and month <= 12
|
||||
end
|
||||
|
||||
is_valid_day: BOOLEAN
|
||||
-- Is the day logical based on month and year?
|
||||
do
|
||||
Result := day >= 1 and then
|
||||
( (day <= 28) or else
|
||||
((month=4 or month=6 or month=9 or month=11) and then day <= 30) or else
|
||||
((month=1 or month=3 or month=5 or month=7 or month=8 or month=10 or month=12) and then day <= 31) or else
|
||||
(month=2 and is_leapyear and day <= 29) )
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
Minimum_representable_date: like Current
|
||||
-- The earliest date that can be represented as an integer.
|
||||
-- This value is dependent on the implementation of `internal' and
|
||||
-- was found by trial and error to be 1 Jan 0001.
|
||||
do
|
||||
create Result
|
||||
Result.set_year (1)
|
||||
Result.set_month (1)
|
||||
Result.set_day (1)
|
||||
end
|
||||
|
||||
Maximum_representable_date: like Current
|
||||
-- The latest date that can be represented as an integer.
|
||||
-- This value is dependent on the implementation of `internal' and
|
||||
-- was found by trial and error to be 18 Oct 1,469,902.
|
||||
do
|
||||
create Result
|
||||
Result.set_year (1_469_902)
|
||||
Result.set_month (10)
|
||||
Result.set_day (18)
|
||||
end
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
duration_anchor: YMD_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
require else
|
||||
not_callable: False
|
||||
do
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
interval_anchor: YMD_INTERVAL
|
||||
-- Anchor for features using intervals.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
require else
|
||||
not_callable: False
|
||||
do
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
invariant
|
||||
|
||||
is_valid: is_valid
|
||||
|
||||
end -- class YMD_TIME
|
||||
|
||||
|
73
jj_temporal/jj_t/classes/ymd_timer.e
Normal file
73
jj_temporal/jj_t/classes/ymd_timer.e
Normal file
@@ -0,0 +1,73 @@
|
||||
note
|
||||
description: "[
|
||||
Timer for hours, minutes, seconds, and miliseconds.
|
||||
]"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: $"
|
||||
revision: "$Revision: $"
|
||||
|
||||
class
|
||||
YMD_TIMER
|
||||
|
||||
inherit
|
||||
|
||||
YMD_INTERVAL
|
||||
undefine
|
||||
duration
|
||||
redefine
|
||||
default_create,
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
TIMER
|
||||
undefine
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Set up the timer
|
||||
do
|
||||
Precursor {YMD_INTERVAL}
|
||||
Precursor {TIMER}
|
||||
create cumulative
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
time_anchor: YMD_TIME
|
||||
-- Anchor for features using times.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
duration_anchor: YMD_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
268
jj_temporal/jj_t/classes/ymdhms_duration.e
Normal file
268
jj_temporal/jj_t/classes/ymdhms_duration.e
Normal file
@@ -0,0 +1,268 @@
|
||||
note
|
||||
description: "[
|
||||
Duration of time described in years, months, days,
|
||||
hours, minutes, and seconds.
|
||||
]"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMDHMS_DURATION
|
||||
|
||||
inherit
|
||||
|
||||
YMD_DURATION
|
||||
rename
|
||||
set as ymd_set,
|
||||
as_string as as_ymd_string
|
||||
redefine
|
||||
default_create,
|
||||
zero, one,
|
||||
set_zero,
|
||||
as_years, as_months, as_days,
|
||||
add, sub, multiply, divide, div, mod, negate, percent_of,
|
||||
is_less,
|
||||
normalize
|
||||
end
|
||||
|
||||
HMS_DURATION
|
||||
rename
|
||||
set as hms_set,
|
||||
as_string as as_hms_string
|
||||
redefine
|
||||
default_create,
|
||||
zero, one,
|
||||
set_zero,
|
||||
as_hours, as_minutes, as_seconds,
|
||||
add, sub, multiply, divide, div, mod, negate, percent_of,
|
||||
is_less,
|
||||
normalize
|
||||
select
|
||||
as_hms_string
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
do
|
||||
Precursor {YMD_DURATION}
|
||||
Precursor {HMS_DURATION}
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
as_string: STRING_8
|
||||
-- The time represented as a string.
|
||||
do
|
||||
Result := as_ymd_string + ":" + as_hms_string
|
||||
end
|
||||
|
||||
zero: like Current
|
||||
-- Neutral element for "+" and "-"
|
||||
do
|
||||
create Result
|
||||
end
|
||||
|
||||
one: like Current
|
||||
-- Neutral element for "*" and "/"
|
||||
do
|
||||
create Result
|
||||
Result.set (1,1,1,1,1,1)
|
||||
end
|
||||
|
||||
as_years: DOUBLE
|
||||
-- Length of duration in years.
|
||||
do
|
||||
Result := years + months / 12 + days / days_per_year +
|
||||
hours / (24 * days_per_year) + minutes / (60 * 24 * days_per_year) +
|
||||
seconds / (60 * 60 * 24 * days_per_year)
|
||||
end
|
||||
|
||||
as_months: DOUBLE
|
||||
-- Length of duration in months.
|
||||
do
|
||||
Result := years * 12 + months + days / days_per_month +
|
||||
hours / hours_per_month + minutes / (60 * hours_per_month) +
|
||||
seconds / (60 * 60 * hours_per_month)
|
||||
end
|
||||
|
||||
as_days: DOUBLE
|
||||
-- Length of duration in days.
|
||||
do
|
||||
Result := years * days_per_year + months * days_per_month + days +
|
||||
hours / 24 + minutes / (24 * 60) + seconds / (24 * 60 * 60)
|
||||
end
|
||||
|
||||
as_hours: DOUBLE
|
||||
-- Length of this duration in hours.
|
||||
do
|
||||
Result := (years * days_per_year + months * days_per_month + days) -- number of days
|
||||
* 24 + hours + minutes / 60 + seconds / 3600
|
||||
end
|
||||
|
||||
as_minutes: DOUBLE
|
||||
-- Length of this duration in minutes.
|
||||
do
|
||||
Result := ((years * days_per_year + months * days_per_month + days) -- number of days
|
||||
* 24 + hours) -- number of hours
|
||||
* 60 + minutes + seconds / 60
|
||||
end
|
||||
|
||||
as_seconds: DOUBLE
|
||||
-- Length of this duration in seconds.
|
||||
do
|
||||
Result := (((years * days_per_year + months * days_per_month + days) -- number of days
|
||||
* 24 + hours) -- number of hours
|
||||
* 60 + minutes) -- number of minutes
|
||||
* 60 + seconds
|
||||
end
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set (a_year, a_month, a_day, a_hour, a_minute, a_second: INTEGER)
|
||||
-- Change years, months, days, hours, minutes, seconds.
|
||||
do
|
||||
ymd_set (a_year, a_month, a_day)
|
||||
hms_set (a_hour, a_minute, a_second)
|
||||
ensure
|
||||
years_set: years = a_year
|
||||
months_set: months = a_month
|
||||
days_set: days = a_day
|
||||
hours_set: hours = a_hour
|
||||
minutes_set: minutes = a_minute
|
||||
seconds_set: seconds = a_second
|
||||
end
|
||||
|
||||
set_zero
|
||||
-- Make the duration be zero length.
|
||||
do
|
||||
ymd_set (0, 0, 0)
|
||||
set_fine (0, 0, 0, 0)
|
||||
end
|
||||
|
||||
|
||||
negate
|
||||
-- Reverse the sign for years, ..., seconds.
|
||||
do
|
||||
Precursor {YMD_DURATION}
|
||||
Precursor {HMS_DURATION}
|
||||
end
|
||||
|
||||
normalize
|
||||
-- Convert to standard format: "13 months" becomes "1 year, 1 month".
|
||||
-- Month and year length is based on 'days_per_month'.
|
||||
do
|
||||
Precursor {HMS_DURATION}
|
||||
set_days (days + hours // 24)
|
||||
set_hours (hours \\ 24)
|
||||
Precursor {YMD_DURATION}
|
||||
end
|
||||
|
||||
add (other: like Current)
|
||||
-- Add other to current.
|
||||
do
|
||||
Precursor {YMD_DURATION} (other)
|
||||
Precursor {HMS_DURATION} (other)
|
||||
end
|
||||
|
||||
sub (other: like Current)
|
||||
-- Subtract other from current.
|
||||
do
|
||||
Precursor {YMD_DURATION} (other)
|
||||
Precursor {HMS_DURATION} (other)
|
||||
end
|
||||
|
||||
multiply (r: DOUBLE)
|
||||
-- Multiply by a factor of 'r'.
|
||||
-- Result is normalized.
|
||||
local
|
||||
v: DOUBLE
|
||||
fract: DOUBLE
|
||||
do
|
||||
v := years * r
|
||||
years := v.floor
|
||||
fract := v - years
|
||||
|
||||
v := months * r + 12 * fract
|
||||
months := v.floor
|
||||
fract := v - months
|
||||
|
||||
v := days * r + days_per_month * fract
|
||||
days := v.floor
|
||||
fract := v - days
|
||||
|
||||
v := hours * r + 24 * fract
|
||||
hours := v.floor
|
||||
fract := v - hours
|
||||
|
||||
v := minutes * r + 60 * fract
|
||||
minutes := v.floor
|
||||
fract := v - minutes
|
||||
|
||||
v := seconds * r + 60 * fract
|
||||
seconds := v.rounded
|
||||
normalize
|
||||
end
|
||||
|
||||
divide (r: DOUBLE)
|
||||
-- Divide by 'r'.
|
||||
-- Result is normalized.
|
||||
do
|
||||
Precursor {HMS_DURATION} (r) -- calculates based on seconds.
|
||||
end
|
||||
|
||||
div (i: INTEGER)
|
||||
-- Integer division.
|
||||
-- Result is normalized.
|
||||
do
|
||||
Precursor {HMS_DURATION} (i) -- calculates based on seconds.
|
||||
end
|
||||
|
||||
mod (i: INTEGER)
|
||||
-- Modulo.
|
||||
-- Result is normalized.
|
||||
do
|
||||
Precursor {HMS_DURATION} (i) -- calculates based on seconds.
|
||||
end
|
||||
|
||||
percent_of (other: like Current): DOUBLE
|
||||
-- What percent of other in length is this one?
|
||||
do
|
||||
Result := as_days / other.as_days -- Days seemed reasonable accuracy.
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
-- Is this duration shorter than other?
|
||||
do
|
||||
Result := Precursor {YMD_DURATION} (other) or else
|
||||
(years = other.years and then months = other.months and then days = other.days and then
|
||||
Precursor {HMS_DURATION} (other))
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
hours_per_year: DOUBLE
|
||||
-- Number of hours in a year.
|
||||
do
|
||||
Result := days_per_year * 24
|
||||
end
|
||||
|
||||
hours_per_month: DOUBLE
|
||||
-- Number of hours in a month.
|
||||
do
|
||||
Result := days_per_month * 24
|
||||
end
|
||||
|
||||
|
||||
|
||||
end -- class YMDHMS_DURATION
|
||||
|
66
jj_temporal/jj_t/classes/ymdhms_duration_constants.e
Normal file
66
jj_temporal/jj_t/classes/ymdhms_duration_constants.e
Normal file
@@ -0,0 +1,66 @@
|
||||
note
|
||||
description: "[
|
||||
Constants for use with {YMDHMS_TIME}, {YMDHMS_DURATION},
|
||||
and {YMDHMS_INTERVAL}.
|
||||
]"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMDHMS_DURATION_CONSTANTS
|
||||
|
||||
feature -- Access
|
||||
|
||||
One_second: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 0, 0, 0, 0, 1)
|
||||
end
|
||||
|
||||
One_minute: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 0, 0, 0, 1, 0)
|
||||
end
|
||||
|
||||
One_hour: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 0, 0, 1, 0, 0)
|
||||
end
|
||||
|
||||
One_day: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 0, 1, 0, 0, 0)
|
||||
end
|
||||
|
||||
One_week: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 0, 7, 0, 0, 0)
|
||||
end
|
||||
|
||||
One_month: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 1, 0, 0, 0, 0)
|
||||
end
|
||||
|
||||
One_quarter: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (0, 3, 0, 0, 0, 0)
|
||||
end
|
||||
|
||||
One_year: YMDHMS_DURATION
|
||||
once
|
||||
create Result
|
||||
Result.set (1, 0, 0, 0, 0, 0)
|
||||
end
|
||||
|
||||
end -- class YMDHMS_DURATION_CONSTANTS
|
60
jj_temporal/jj_t/classes/ymdhms_interval.e
Normal file
60
jj_temporal/jj_t/classes/ymdhms_interval.e
Normal file
@@ -0,0 +1,60 @@
|
||||
note
|
||||
description: "[
|
||||
A span of time consisting of a start-time, finish-time
|
||||
and duration described in terms of years, months,
|
||||
days, hours, minutes, and seconds. Positive durations only.
|
||||
]"
|
||||
names: "ymdhms_interval, interval, time_span, time_interval, span"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMDHMS_INTERVAL
|
||||
|
||||
inherit
|
||||
|
||||
HMS_INTERVAL
|
||||
undefine
|
||||
default_create,
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
YMD_INTERVAL
|
||||
redefine
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
time_anchor: YMDHMS_TIME
|
||||
-- Anchor for features using times.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
do
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
duration_anchor: YMDHMS_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
do
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
end
|
391
jj_temporal/jj_t/classes/ymdhms_time.e
Normal file
391
jj_temporal/jj_t/classes/ymdhms_time.e
Normal file
@@ -0,0 +1,391 @@
|
||||
note
|
||||
description: "[
|
||||
An exact point of time of a particular day. A Year, Month, Day,
|
||||
Hour, Minute, Second - time (ie. a date and time).
|
||||
]"
|
||||
names: "date, time, date_and_time"
|
||||
author: "Jimmy J. Johnson"
|
||||
copyright: "Copyright 2009, Jimmy J. Johnson"
|
||||
license: "Eiffel Forum License v2 (see forum.txt)"
|
||||
URL: "$URL:$"
|
||||
date: "$Date: 2009-06-25 21:37:23 -0400 (Thu, 25 Jun 2009) $"
|
||||
revision: "$Revision: 7 $"
|
||||
|
||||
class
|
||||
YMDHMS_TIME
|
||||
|
||||
inherit
|
||||
|
||||
YMD_TIME
|
||||
rename
|
||||
set as set_ymd_time,
|
||||
as_days as as_seconds,
|
||||
from_days as from_seconds
|
||||
redefine
|
||||
default_create,
|
||||
set_now,
|
||||
set_now_utc,
|
||||
set_now_utc_fine,
|
||||
is_less,
|
||||
is_valid,
|
||||
add_duration,
|
||||
time_between,
|
||||
-- normalize,
|
||||
truncate_to_years,
|
||||
truncate_to_months,
|
||||
as_string,
|
||||
as_seconds,
|
||||
from_seconds,
|
||||
from_string,
|
||||
is_valid_string_representation,
|
||||
is_valid_integer_representation,
|
||||
is_representable_as_integer,
|
||||
duration_anchor,
|
||||
interval_anchor
|
||||
end
|
||||
|
||||
HMS_TIME
|
||||
rename
|
||||
set as set_hms_time
|
||||
redefine
|
||||
default_create,
|
||||
set_now,
|
||||
set_now_utc,
|
||||
set_now_fine,
|
||||
set_now_utc_fine,
|
||||
is_less,
|
||||
is_valid,
|
||||
add_duration,
|
||||
time_between,
|
||||
seconds_between,
|
||||
add_hours,
|
||||
-- normalize,
|
||||
truncate_to_hours,
|
||||
truncate_to_minutes,
|
||||
as_string,
|
||||
as_seconds,
|
||||
from_seconds,
|
||||
from_string,
|
||||
is_valid_string_representation,
|
||||
is_valid_integer_representation,
|
||||
is_representable_as_integer,
|
||||
Duration_anchor,
|
||||
Interval_anchor
|
||||
select
|
||||
from_seconds
|
||||
end
|
||||
|
||||
create
|
||||
default_create,
|
||||
set_now,
|
||||
set_now_utc,
|
||||
set_now_fine,
|
||||
set_now_utc_fine,
|
||||
from_seconds,
|
||||
from_string
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Create an instance with todays date at midnight.
|
||||
do
|
||||
Precursor {HMS_TIME}
|
||||
Precursor {YMD_TIME}
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
as_string: STRING
|
||||
-- String representation of Current in a compact form.
|
||||
do
|
||||
Result := Precursor {YMD_TIME}
|
||||
Result.append ("T")
|
||||
Result.append (Precursor {HMS_TIME})
|
||||
end
|
||||
|
||||
as_seconds: INTEGER
|
||||
-- The number of seconds from midnight (00:00:00)
|
||||
-- on 1 Jan 1970 to the Current time.
|
||||
local
|
||||
days: INTEGER
|
||||
do
|
||||
days := Precursor {YMD_TIME}
|
||||
Result := days * 24 * 60 * 60 + Precursor {HMS_TIME}
|
||||
end
|
||||
|
||||
feature -- Element Change
|
||||
|
||||
from_string (a_string: STRING)
|
||||
-- Change Current to the time represented by `a_string'.
|
||||
-- It must be in the format as provided by `as_string'.
|
||||
local
|
||||
pos: INTEGER
|
||||
do
|
||||
pos := a_string.index_of ('T', 1)
|
||||
Precursor {YMD_TIME} (a_string.substring (1, pos - 1))
|
||||
Precursor {HMS_TIME} (a_string.substring (pos + 1, a_string.count))
|
||||
end
|
||||
|
||||
from_seconds (a_seconds: INTEGER)
|
||||
-- Change Current to the time represented by `a_seconds'.
|
||||
-- `A_seconds' is assumed to be the number of seconds since 1 Jan 1970.
|
||||
-- It must represent a date that is not BC.
|
||||
do
|
||||
set (1970, 1, 1, 0, 0, 0)
|
||||
add_seconds (a_seconds)
|
||||
end
|
||||
|
||||
set_now
|
||||
-- Initialize the instance from the system clock unsing the
|
||||
-- current time zone.
|
||||
do
|
||||
Precursor {HMS_TIME}
|
||||
Precursor {YMD_TIME}
|
||||
end
|
||||
|
||||
set_now_utc
|
||||
-- Initialize the instance from the system clock unsing GMT.
|
||||
do
|
||||
Precursor {HMS_TIME}
|
||||
Precursor {YMD_TIME}
|
||||
end
|
||||
|
||||
set_now_fine
|
||||
-- Initialize the instance from the system clock using the current
|
||||
-- time zone and including milliseconds.
|
||||
do
|
||||
set_now
|
||||
Precursor {HMS_TIME}
|
||||
end
|
||||
|
||||
set_now_utc_fine
|
||||
-- Initialize the instance from the system clock using the GMT and
|
||||
-- including milliseconds.
|
||||
do
|
||||
set_now_utc
|
||||
Precursor {HMS_TIME}
|
||||
end
|
||||
|
||||
set (a_year, a_month, a_day, a_hour, a_minute, a_second: INTEGER)
|
||||
-- Change the 'year', ..., 'second'.
|
||||
require
|
||||
year_valid: a_year /= 0;
|
||||
month_valid: 1 <= a_month and a_month <= 12;
|
||||
day_valid: 1 <= a_day and a_day <= 31;
|
||||
hour_valid: 0 <= a_hour and a_hour <= 23;
|
||||
minute_valid: 0 <= a_minute and a_minute <= 59;
|
||||
second_valid: 0 <= a_second and a_second <= 59
|
||||
do
|
||||
set_ymd_time (a_year, a_month, a_day);
|
||||
set_hms_time (a_hour, a_minute, a_second);
|
||||
end
|
||||
|
||||
truncate_to_years
|
||||
-- Set to midnight on the first day of month 1.
|
||||
-- Use when all but the `year' is to be ignored.
|
||||
do
|
||||
Precursor {YMD_TIME}
|
||||
set_hms_time (0, 0, 0)
|
||||
ensure then
|
||||
year_unchanged: year = old year
|
||||
month_one: month = 1
|
||||
day_one: day = 1
|
||||
hour_zero: hour = 0
|
||||
minute_zero: minute = 0
|
||||
second_zero: second = 0
|
||||
end
|
||||
|
||||
truncate_to_months
|
||||
-- Set to midnight on the first day of the current month.
|
||||
-- Use when all but the `year' and `month' is to be ignored.
|
||||
do
|
||||
Precursor {YMD_TIME}
|
||||
set_hms_time (0, 0, 0)
|
||||
ensure then
|
||||
year_unchanged: year = old year
|
||||
month_unchaged: month = old month
|
||||
day_one: day = 1
|
||||
hour_zero: hour = 0
|
||||
minute_zero: minute = 0
|
||||
second_zero: second = 0
|
||||
end
|
||||
|
||||
truncate_to_days
|
||||
-- Set to midnight on the current day.
|
||||
-- Use when the time portion of the date is to be ignored.
|
||||
do
|
||||
set_hms_time (0, 0, 0)
|
||||
ensure then
|
||||
year_unchanged: year = old year
|
||||
month_unchaged: month = old month
|
||||
day_unchaged: day = old day
|
||||
hour_zero: hour = 0
|
||||
minute_zero: minute = 0
|
||||
second_zero: second = 0
|
||||
end
|
||||
|
||||
truncate_to_hours
|
||||
-- Set the `hour', `second', and `millisecond' to zero.
|
||||
-- Used when these portions of the time are to be ignored.
|
||||
do
|
||||
set (year, month, day, hour, 0, 0)
|
||||
end
|
||||
|
||||
truncate_to_minutes
|
||||
do
|
||||
set (year, month, day, hour, minute, 0)
|
||||
end
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
add_duration (a_duration: like duration_anchor)
|
||||
-- Add a length of time (in years, months, days,
|
||||
-- hours, minutes, and seconds) to the time.
|
||||
do
|
||||
Precursor {HMS_TIME} (a_duration)
|
||||
add_days (overflow)
|
||||
clear_overflow
|
||||
Precursor {YMD_TIME} (a_duration)
|
||||
ensure then
|
||||
no_overflowing_days: overflow = 0
|
||||
end
|
||||
|
||||
add_hours (a_number: INTEGER)
|
||||
-- Add `a_number' of hours to the current time
|
||||
do
|
||||
Precursor {HMS_TIME} (a_number)
|
||||
add_days (overflow)
|
||||
clear_overflow
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_representable_as_integer: BOOLEAN
|
||||
-- Can Current be represented as an integer?
|
||||
do
|
||||
Result := Precursor {HMS_TIME} and then Precursor {YMD_TIME}
|
||||
end
|
||||
|
||||
feature -- Querry
|
||||
|
||||
time_between (other: like Current): like duration_anchor
|
||||
-- The difference between two dates as a time span or duration.
|
||||
local
|
||||
larger, smaller: like Current
|
||||
y, mon, d, h, m, s: INTEGER
|
||||
do
|
||||
larger := max (other)
|
||||
smaller := min (other)
|
||||
y := larger.year - smaller.year
|
||||
mon := larger.month - smaller.month
|
||||
d := larger.day - smaller.day
|
||||
h := larger.hour - smaller.hour
|
||||
m := larger.minute - smaller.minute
|
||||
s := larger.second - smaller.second
|
||||
if s < 0 then
|
||||
s := s + 60
|
||||
m := m - 1
|
||||
end
|
||||
if m < 0 then
|
||||
m := m + 60
|
||||
h := h - 1
|
||||
end
|
||||
if h < 0 then
|
||||
h := h + 24
|
||||
d := d - 1
|
||||
end
|
||||
if d < 0 then
|
||||
d := d + smaller.last_day_of_month
|
||||
mon := mon - 1
|
||||
end
|
||||
if mon < 0 then
|
||||
mon := mon + 12
|
||||
y := y - 1
|
||||
end
|
||||
create Result
|
||||
Result.set (y, mon, d, h, m, s)
|
||||
if Current < other then
|
||||
Result.negate
|
||||
end
|
||||
end
|
||||
|
||||
seconds_between (a_other: like Current): INTEGER
|
||||
-- The number of seconds between Current and `a_other'.
|
||||
do
|
||||
Result := days_between (a_other) * 24 * 60 * 60 + Precursor {HMS_TIME} (a_other)
|
||||
end
|
||||
|
||||
is_valid_string_representation (a_string: STRING): BOOLEAN
|
||||
-- Is `a_string' in a format that can be used to initialize Current?
|
||||
local
|
||||
i: INTEGER
|
||||
ds, ts: STRING
|
||||
do
|
||||
if a_string /= Void then
|
||||
i := a_string.index_of ('T', 1)
|
||||
ds := a_string.substring (1, i - 1)
|
||||
ts := a_string.substring (i + 1, a_string.count)
|
||||
Result := Precursor {YMD_TIME} (ds) and then Precursor {HMS_TIME} (ts)
|
||||
end
|
||||
end
|
||||
|
||||
is_valid_integer_representation (a_integer: INTEGER): BOOLEAN
|
||||
-- Is `a_integer' in range to be converted to a time?
|
||||
do
|
||||
Result := Precursor {HMS_TIME} (a_integer) and then
|
||||
Precursor {YMD_TIME} (a_integer)
|
||||
end
|
||||
|
||||
feature -- Comparison
|
||||
|
||||
is_less alias "<" (other: like Current): BOOLEAN
|
||||
-- Does this date_and_time come before 'other'
|
||||
do
|
||||
Result := year < other.year or else
|
||||
((year = other.year) and (month < other.month)) or else
|
||||
((year = other.year) and (month = other.month) and (day < other.day)) or else
|
||||
((year = other.year) and (month = other.month) and (day = other.day) and
|
||||
(hour < other.hour)) or else
|
||||
((year = other.year) and (month = other.month) and (day = other.day) and
|
||||
(hour = other.hour) and (minute < other.minute)) or else
|
||||
((year = other.year) and (month = other.month) and (day = other.day) and
|
||||
(hour = other.hour) and (minute = other.minute) and (second < other.second)) or else
|
||||
((year = other.year) and (month = other.month) and (day = other.day) and
|
||||
(hour = other.hour) and (minute = other.minute) and (second = other.second) and
|
||||
(millisecond < other.millisecond))
|
||||
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
is_valid: BOOLEAN
|
||||
-- Is the date and time logical?
|
||||
do
|
||||
Result := Precursor {YMD_TIME} and Precursor {HMS_TIME}
|
||||
end
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
duration_anchor: YMDHMS_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
interval_anchor: YMDHMS_INTERVAL
|
||||
-- Anchor for features using intervals.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
end
|
77
jj_temporal/jj_t/classes/ymdhms_timer.e
Normal file
77
jj_temporal/jj_t/classes/ymdhms_timer.e
Normal file
@@ -0,0 +1,77 @@
|
||||
note
|
||||
description: "Summary description for {YMDHMS_TIMER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
YMDHMS_TIMER
|
||||
|
||||
inherit
|
||||
|
||||
YMDHMS_INTERVAL
|
||||
undefine
|
||||
duration
|
||||
redefine
|
||||
default_create,
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
HMS_TIMER
|
||||
undefine
|
||||
duration
|
||||
redefine
|
||||
default_create,
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
end
|
||||
|
||||
YMD_TIMER
|
||||
undefine
|
||||
time_anchor,
|
||||
duration_anchor
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
-- Set up the timer
|
||||
do
|
||||
Precursor {YMDHMS_INTERVAL}
|
||||
Precursor {YMD_TIMER}
|
||||
create cumulative
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Anchors (for covariant redefinitions)
|
||||
|
||||
time_anchor: YMDHMS_TIME
|
||||
-- Anchor for features using times.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
duration_anchor: YMDHMS_DURATION
|
||||
-- Anchor for features using durations.
|
||||
-- Not to be called; just used to anchor types.
|
||||
-- Declared as a feature to avoid adding an attribute.
|
||||
once
|
||||
check
|
||||
do_not_call: False then
|
||||
-- Because give no info; simply used as anchor.
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
Reference in New Issue
Block a user