added jj_temporal source code

This commit is contained in:
2024-06-19 15:01:51 +02:00
parent d551f35d2f
commit 4df573d730
93 changed files with 13000 additions and 1 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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/classes/timer.e Normal file
View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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