BasicTime.mesa
Copyright Ó 1985, 1986, 1987, 1988, 1991 by Xerox Corporation. All rights reserved.
For Portable Cedar
Russ Atkinson (RRA) July 11, 1988 1:49:18 pm PDT
Beach, February 27, 1985 10:17:35 am PST
Doug Wyatt, January 16, 1987 5:21:52 pm PST
Carl Hauser, January 19, 1988 10:18:07 am PST
BasicTime: CEDAR DEFINITIONS = BEGIN
Errors
OutOfRange: ERROR;
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
TimeNotKnown: ERROR;
Raised by "Now" if we don't know the time.
TimeParametersNotKnown: ERROR;
Raised by "Unpack" if we don't know the time zone or daylight savings time information.
Part I: Fine-grain timer
Pulses: TYPE = CARD;
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.
GetClockPulses: PROC RETURNS [Pulses];
Returns the current value of the fine-grain clock
PulsesToMicroseconds: PROC [Pulses] RETURNS [CARD];
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).
PulsesToSeconds: PROC [Pulses] RETURNS [REAL];
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.
MicrosecondsToPulses: PROC [CARD] RETURNS [Pulses];
Part II: Packed times
GMT: TYPE[UNITS[INT32]];
"GMT" provides a compact representation of a time, specified in seconds, which is efficient to obtain, to compare, and to modify.
ExtendedGMT: TYPE = RECORD [
gmt: GMT,
usecs: INT[0..1000000)
];
nullGMT: GMT = LOOPHOLE[LAST[INT32]];
A value such that ~(nullGMT IN [earliestGMT..latestGMT]). Illegal as argument to most procedures.
earliestGMT: GMT;
the earliest possible value of GMT (beginning of 1968)
latestGMT: GMT;
the latest possible value of GMT (sometime in 2036)
Now: PROC RETURNS [GMT];
The present time, if known. Raises "TimeNotKnown" if the time isn't known.
ExtendedNow: PROC [] RETURNS [ExtendedGMT];
Period: PROC [from, to: GMT] RETURNS [INT];
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.
Update: PROC [base: GMT, period: INT] RETURNS [GMT];
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.
ToPupTime: PROC [GMT] RETURNS [CARD];
Returns time according to the Alto/Pup time standard. No errors.
ToNSTime: PROC [GMT] RETURNS [CARD];
Returns time according to the Xerox NS protocol time standard. No errors.
FromPupTime: PROC [CARD] RETURNS [GMT];
Accepts time according to the Alto/Pup time standard. Raises "OutOfRange" for times earlier than 1968.
FromNSTime: PROC [CARD] RETURNS [GMT];
Accepts time according to the Xerox NS protocol time standard. Raises "OutOfRange" for times beyond about 2036.
Part III: Unpacked times
Unpacked: TYPE = RECORD [
"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.
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,
When calling "Pack": "zone" and "dst" are either ignored or override local time parameters
zone: Zone ¬ unspecifiedZone,
dst: {yes, no, unspecified} ¬ unspecified,
Remaining fields are redundant, and are always ignored by "Pack"
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];
If the local zone isn't known, assumes zone 0 and non-DST (GMT).
unspecifiedTP: ZoneAndDST ~ [zone: unspecifiedZone, beginDST: 366, endDST: 366];
UnpackZ: PROC [time: GMT, tp: ZoneAndDST ¬ unspecifiedTP] RETURNS [Unpacked];
If tp.zone=unspecifiedZone, assumes zone 0 and non-DST (GMT).
Pack: PROC [unpacked: Unpacked] RETURNS [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.
UnpackedPeriod: TYPE = RECORD [
... provides an unpacked representation of a time period specified in seconds.
hours: INT ¬ 0,
minutes: [0..minutesPerHour) ¬ 0,
seconds: [0..secondsPerMinute) ¬ 0,
negative: BOOL ¬ FALSE
];
UnpackPeriod: PROC [seconds: INT] RETURNS [UnpackedPeriod];
Unpacks a time period specified in seconds.
PackPeriod: PROC [UnpackedPeriod] RETURNS [seconds: INT];
Returns a time period in seconds.
Raises "OutOfRange" if the unpacked period is too large for an INT.
Part IV: Zone/dst information
ZoneAndDST: TYPE = RECORD [
zone: Zone,
beginDST, endDST: [0..366] -- DST starts/stops at 2 a.m.
];
GetZoneAndDST: PROC RETURNS [ZoneAndDST];
Returns the currently believed local zone and DST parameters. "unspecifiedZone" is returned if they aren't currently known.
END.
Carl Hauser, January 17, 1988 3:51:10 pm PST
Folded BasicTimeExtras from Cedar7.0 release in converting for Portable Cedar.
Also, GetClockPulses is still commented out pending decision on how this works in Portable Cedar.
Russ Atkinson (RRA) July 11, 1988 11:16:20 am PDT
added calls to XR routines for GetClockPulses, PulsesToMicroseconds, PulsesToSeconds, MicrosecondsToPulses