DIRECTORY PrincOps USING [aRCLK, zMISC]; BasicTime: CEDAR DEFINITIONS = BEGIN OutOfRange: ERROR; TimeNotKnown: ERROR; TimeParametersNotKnown: ERROR; Pulses: TYPE = LONG CARDINAL; GetClockPulses: PROC RETURNS[Pulses] = TRUSTED MACHINE CODE { PrincOps.zMISC, PrincOps.aRCLK }; PulsesToMicroseconds: PROC[Pulses] RETURNS[LONG CARDINAL]; PulsesToSeconds: PROC[Pulses] RETURNS[REAL]; MicrosecondsToPulses: PROC[LONG CARDINAL] RETURNS[Pulses]; GMT: TYPE[2]; nullGMT: GMT = LOOPHOLE[LAST[INT]]; earliestGMT: GMT; latestGMT: GMT; Now: PROC RETURNS [GMT]; Period: PROC[from, to: GMT] RETURNS [INT]; Update: PROC[base: GMT, period: INT] RETURNS [GMT]; ToPupTime: PROC[GMT] RETURNS[LONG CARDINAL]; ToNSTime: PROC[GMT] RETURNS [LONG CARDINAL]; FromPupTime: PROC[LONG CARDINAL] RETURNS[GMT]; FromNSTime: PROC[LONG CARDINAL] RETURNS[GMT]; Unpacked: TYPE = RECORD[ year: [0..2050] _ 0, month: MonthOfYear _ unspecified, day: [0..daysPerMonth] _ 0, -- first day of the month is 1 hour: [0..hoursPerDay] _ 24, minute: [0..minutesPerHour] _ 60, second: [0..secondsPerMinute] _ 60, zone: Zone _ unspecifiedZone, dst: {yes, no, unspecified} _ unspecified, weekday: DayOfWeek _ unspecified, secondsThisYear: INT _ LAST[INT], daysThisYear: [0..daysPerYear] _ daysPerYear ]; MonthOfYear: TYPE = {January, February, March, April, May, June, July, August, September, October, November, December, unspecified}; DayOfWeek: TYPE = {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, unspecified}; Zone: TYPE = [-720..+721]; -- California is +60*8. 721 means unspecified. unspecifiedZone: Zone = +721; daysPerMonth: INT = 31; hoursPerDay: INT = 24; minutesPerHour: INT = 60; secondsPerMinute: INT = 60; daysPerYear: INT = 366; secondsPerYear: INT = secondsPerMinute * minutesPerHour * hoursPerDay * daysPerYear; Unpack: PROC[time: GMT] RETURNS[Unpacked]; Pack: PROC[unpacked: Unpacked] RETURNS[GMT]; ZoneAndDST: TYPE = RECORD[ zone: Zone, beginDST, endDST: [0..366] -- DST starts/stops at 2 a.m. ]; SetZoneAndDST: PROC[ZoneAndDST]; GetZoneAndDST: PROC RETURNS[ZoneAndDST]; SetTime: PROC; END. BasicTime.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Andrew Birrell August 8, 1983 10:56 am Levin, September 22, 1983 11:40 am Russ Atkinson (RRA) February 1, 1985 5:53:24 pm PST Beach, February 27, 1985 10:17:35 am PST Errors Some conversion was given a time which could not be converted. The valid ranges are: Alto: 1901 to 2036 (232 seconds) NS: 1968 to 2103 (Alto offset to 1968) GMT: 1968 to 2036 (231 seconds, same expiry date as Alto) Unpacked: approximately forever Raised by "Now" if we don't know the time. Raised by "Unpack" if we don't know the time zone or daylight savings time information. Part I: Fine-grain timer Pulses are a machine dependent measure of elapsed time. One pulse is somewhere between 1 microseconds and 100 microseconds long. The actual pulse frequency is processor dependent. See the ProcessorFace comments. Returns the current value of the fine-grain clock Returns the number of microseconds. The calculation is careful to avoid unnecessary loss of precision. Undefined if the result would exceed 232-1 microseconds (about one hour). Returns the number of seconds. Beware: reals have only 24 bits of precision, so the fractional part of the result is not as accurate as calling PulsesToMicroseconds. However, the result never overflows. Part II: Packed times "GMT" provides a compact representation of a time, specified in seconds, which is efficient to obtain, to compare, and to modify. A value such that ~(nullGMT IN [earliestGMT..latestGMT]). Illegal as argument to most procedures. the earliest possible value of GMT (beginning of 1968) the latest possible value of GMT (sometime in 2036) The present time, if known. Raises "TimeNotKnown" if the time isn't known. The number of seconds between the times. Positive iff "to" is later than "from". Since the range of GMT is only 31 bits, the interval can always be represented in an INT. Returns the time "period" seconds later than "base" (earlier iff "period" is negative). Raises "OutOfRange" if the result would be before 1968 or after 2036. Returns time according to the Alto/Pup time standard. No errors. Returns time according to the Xerox NS protocol time standard. No errors. Accepts time according to the Alto/Pup time standard. Raises "OutOfRange" for times earlier than 1968. Accepts time according to the Xerox NS protocol time standard. Raises "OutOfRange" for times beyond about 2036. Part III: Unpacked times "Unpacked" provides a representation of a time, specified in seconds, which is easy to interpret in ways meaningful to humans, such as years/months/days/etc. Each field has an default "unspecified" value for use by Time.SmartPack. When calling "Pack": "zone" and "dst" are either ignored or override local time parameters Remaining fields are redundant, and are always ignored by "Pack" If the local zone isn't known, assumes zone 0 and non-DST (GMT). Raises "TimeParametersNotKnown" if the time zone or DST info aren't sufficiently specified; raises "OutOfRange" for times before 1968 or after 2036. If unpacked.zone = unspecifiedZone, then the "zone" field of "unpacked" is ignored and the local time parameters are used; if unpacked.dst = unspcified, then DST is calculated using the local time parameters; otherwise the values from "unpacked" are used and the local values are ignored. Part IV: Finding and setting time and zone/dst information Asserts that these are the local time zone and DST parameters. Not a call for mere mortals: the package usually does an adequate job of determining these parameters for itself. Returns the currently believed local zone and DST parameters. "unspecifiedZone" is returned if they aren't currently known. Make best efforts to set the correct time from suitable sources (e.g. Pup or NS time servers). If the ZoneAndDST parameters are currently unknown, also sets them. Not a call for mere mortals: the effect of this call usually happen automatically when needed. ʘcodešœ™Kšœ Ïmœ1™