timestamp.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-------------------------> GNU Sather - sourcefile <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute and/or modify it under the terms of the GNU Library General --
-- Public License (LGPL) as published by the Free Software Foundation; --
-- either version 2 of the license, or (at your option) any later version. --
-- This library is distributed in the hope that it will be useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details. --
-- The license text is also available from: Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --
--------------> Please email comments to <bug-sather@gnu.org> <--------------
immutable class TIME_STAMP < $ORDERED{TIME_STAMP}, $HASH, $TEXT
immutable class TIME_STAMP < $ORDERED{TIME_STAMP}, $HASH, $TEXT is
-- This class provides time and date information together as used
-- in both the DATES and TIMES classes.
-- Version 1.2 Oct 98. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 10 Dec 96 kh Original
-- 14 Jun 97 kh Separated from dates and times classes.
-- 30 Oct 98 kh Separated out conversion, added pre/posts.
include COMPARABLE ;
include TIME_STAMP_STR ;
private attr days : CARD ;
private attr millisecs : CARD ;
private const Millisecs_per_Day : CARD := 1000 * 24 * 60 * 60 ;
create(
day : DATES,
time : TIMES
) : SAME is
-- This routine takes a given date and time to create a time-stamp. The
-- purpose of this routine is to allow the creation of arbitrary time stamps
-- which could be assembled from a date and time produced in any of the
-- possible ways provided for those classes.
return days(day.count).millisecs(time.count)
end ;
create(
day_cnt : CARD,
millis : CARD
) : SAME
pre (millis < Millisecs_per_Day)
post true
is
-- This routine takes the parameters to be the number of complete days
-- elapsed since the OS dependent base date and millis to be the number of
-- milliseconds elapsed since midnight on the previous day.
return days(day_cnt).millisecs(millis)
end ;
nil : SAME is
-- This feature returns the nil time stamp..
return days(0).millisecs(CARD::nil)
end ;
now : SAME is
-- This procedure returns the current date/time as known by the
-- system clock. The date/time value (and the precision of that value)
-- returned depends upon the setting of the clock!
me : SAME ;
loc_stamp : OS_TIME := OS_TIME::time_stamp ;
return me.days(loc_stamp.days).millisecs(loc_stamp.millisecs)
end ;
num_days : CARD is
-- This routine returns the day component of the time stamp.
return days
end ;
num_milliseconds : CARD is
-- This routine returns the number of milliseconds since midnight which
-- are represented by this time stamp.
return millisecs
end ;
is_eq(
other : SAME
) : BOOL is
-- This predicate returns true if and only if self and other represent
-- the same date/time.
return (days = other.days)
and (millisecs = other.millisecs)
end ;
is_lt(
other : SAME
) : BOOL is
-- This predicate returns true if and only if self represents an earlier
-- date/time than other.
return (days < other.days)
or ((days = other.days)
and (millisecs < other.millisecs))
end ;
is_nil : BOOL is
-- This predicate returns true if and only if self is a nil time stamp.
return (days = 0)
and (millisecs = CARD::nil)
end ;
plus(
delay : ELAPSED
) : SAME
pre true
post (((delay.millisecs + millisecs) >= Millisecs_per_Day)
and ((result.millisecs = (delay.millisecs +
millisecs - Millisecs_per_Day))
and (result.days = (days + delay.days + 1))))
or ((result.millisecs = delay.millisecs + millisecs)
and (result.days = (days + delay.days)))
is
-- This routine returns the result of adding the given elapsed time to
-- self. If the clock goes past midnight then the time given is on the
-- following day!
res : SAME ;
loc_time : CARD := delay.millisecs + millisecs ;
if loc_time >= Millisecs_per_Day then
res := res.millisecs(loc_time - Millisecs_per_Day) ;
res := res.days(days + delay.days + 1)
else
res := res.millisecs(loc_time) ;
res := res.days(days + delay.days)
end ;
return res
end ;
private subtract(
from,
sub : SAME
) : ELAPSED
pre (from >= sub)
post ((sub.millisecs > from.millisecs)
and (((from.days > sub.days)
and (result.days = (from.days - sub.days - 1)))
or ((from.days = sub.days)
and (result.days = 0)))
and (result.millisecs = (from.millisecs +
Millisecs_per_Day - sub.millisecs)))
or((sub.millisecs <= from.millisecs)
and (result.days = (from.days - sub.days))
and (result.millisecs = (from.millisecs - sub.millisecs)))
is
-- This private routine subtracts sub, returning the difference as
-- an elapsed time.
num_days : CARD := from.days - sub.days ;
millis : CARD := from.millisecs ;
if sub.millisecs > from.millisecs then
millis := millis + Millisecs_per_Day ;
if num_days > 0 then
num_days := num_days - 1
end
end ;
return ELAPSED::create(num_days,(millis - sub.millisecs))
end ;
minus(
other : SAME
) : ELAPSED
pre true
post ((self < other)
and (result = subtract(other,self)))
or ((self >= other)
and (result = subtract(self,other)))
is
-- This returns the result of subtracting other from self. The result
-- is the time difference which is always positive!
if self < other then
return subtract(other,self)
else
return subtract(self,other)
end
end ;
minus(
other : ELAPSED
) : SAME
pre (self >= create(other.days,other.millisecs))
post (result.days = (self - create(other.days,other.millisecs)).days)
and (result.millisecs = (self -
create(other.days,other.millisecs)).millisecs)
is
-- This returns the result of subtracting the given elapsed time from
-- self. If the result would be on the previous day then the clock time
-- on that day is returned!
--
-- WARNING This makes use of the fact that the representation of an elapsed
-- time is the same as that of a time-stamp!!
res : ELAPSED := self - create(other.days,other.millisecs) ;
return days(res.days).millisecs(res.millisecs)
end ;
private zone_stamp(
lib : LIBCHARS
) : SAME
pre ~void(lib)
post ~((result.days = 0)
and (result.millisecs = 0))
is
-- This routine returns a time stamp corresponding to self in the
-- cultural region specified.
loc_dt : TEMPORAL := lib.culture.date_time ;
loc_zone : TIME_ZONE := loc_dt.time_zone ;
res : SAME ;
if void(loc_zone) then -- assume it must be local!!
return self
else
if loc_zone.is_west_of_UTC(self) then
res := self - loc_zone.time_difference(self)
else
res := self + loc_zone.time_difference(self)
end
end ;
return res
end ;
private to_UTC(
lib : LIBCHARS
) : SAME
pre ~void(lib)
post ~((result.days = 0)
and (result.millisecs = 0))
is
-- This routine returns a time stamp corresponding to self in the
-- cultural region specified.
loc_dt : TEMPORAL := lib.culture.date_time ;
loc_zone : TIME_ZONE := loc_dt.time_zone ;
res : SAME ;
if void(loc_zone) then -- Can't do it so ...
return void
else
if loc_zone.is_west_of_UTC then
res := self + loc_zone.time_difference
else
res := self - loc_zone.time_difference
end
end ;
return res
end ;
date : DATES
pre true
post (result.count = self.days)
is
-- This routine returns the date component of self.
return DATES::create(self)
end ;
era_date : ERA_DATES
pre true
post (result.count = self.days)
is
-- This routine returns the date component of self in the form of the
-- culture-dependent non-Gregorian calendar.
return ERA_DATES::create(self)
end ;
time : TIMES
pre true
post (result.count = self.millisecs)
is
-- This routine returns the time component of self.
return TIMES::create(self)
end ;
hash : CARD
pre true -- irrespective of value
post true -- irrespective of result
is
-- This routine is provided to enable the establishment of date/time
-- based queues/lists.
dbits : NUM_BITS := NUM_BITS::create(days) ;
mbits : NUM_BITS := NUM_BITS::create(millisecs) ;
return dbits.convolve(mbits).hash
end ;
end ; -- TIME_STAMP