<<>> <> <> <> <> <<>> DIRECTORY HostTime, Real, UnixSysCalls, UnixTypes; HostTimeUnixImpl: CEDAR PROGRAM IMPORTS Real, UnixSysCalls EXPORTS HostTime ~ BEGIN Time: TYPE = HostTime.Time; ExtendedGMT: TYPE = HostTime.ExtendedGMT; ZoneAndDST: TYPE = HostTime.ZoneAndDST; gmtBaseYear: CARDINAL = 1968; -- really should come from BasicTime, but it's not exported unixBaseYear: CARDINAL = 1970; -- Unix times start at 00:00Z Jan 1, 1978. unixCorrection: CARD = (((unixBaseYear-gmtBaseYear)*365+1) * 24*60*60) -- '68 was a leap year -- ; HostTimeFromExtendedGMT: PUBLIC PROC [egmt: ExtendedGMT] RETURNS [time: Time ¬ [0, 0, 0, 0]] ~ { time.a ¬ -unixCorrection + LOOPHOLE[egmt.gmt]; time.b ¬ egmt.usecs; }; ExtendedGMTFromHostTime: PUBLIC PROC [time: Time] RETURNS [egmt: ExtendedGMT] ~ { egmt.gmt ¬ LOOPHOLE[time.a+unixCorrection]; egmt.usecs ¬ time.b; }; GetTime: PUBLIC PROC [] RETURNS [time: Time ¬ [0, 0, 0, 0]] ~ TRUSTED { timeVal: UnixTypes.TimeVal ¬ [0, 0]; [] ¬ UnixSysCalls.GetTimeOfDay[tp: @timeVal, tzp: NIL]; time.a ¬ timeVal.sec; time.b ¬ timeVal.usec; }; TimeToMicroseconds: PUBLIC PROC [time: Time] RETURNS [CARD] ~ { RETURN [CARD[time.b]+LOOPHOLE[time.a, CARD]*1000000]; }; MicrosecondsToTime: PUBLIC PROC [usecs: CARD] RETURNS [time: Time] ~ { RETURN [[usecs/1000000, usecs MOD 1000000, 0, 0]]; }; TimeToSeconds: PUBLIC PROC [time: Time] RETURNS [REAL] ~ { <> RETURN [time.a + time.b*1.0e-6]; }; SecondsToTime: PUBLIC PROC [secs: REAL] RETURNS [Time] ~ { RETURN [[Real.Floor[secs], Real.Round[1000000*(secs-Real.Floor[secs])], 0, 0]]; }; GetZoneAndDST: PUBLIC PROC [] RETURNS [tp: ZoneAndDST] ~ TRUSTED { unixTimeZone: UnixTypes.TimeZone; TRUSTED {[] ¬ UnixSysCalls.GetTimeOfDay[tp: NIL, tzp: @unixTimeZone]}; tp.zone ¬ unixTimeZone.minutesWest; <> IF unixTimeZone.dstTime # 0 THEN { tp.beginDST ¬ 98; tp.endDST ¬ 305; } ELSE { tp.beginDST ¬ 366; -- never use dst tp.endDST ¬ 1; }; }; END. <> <> <<>>