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