Tempus.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Teitelman on: July 2, 1983 8:41 pm
Maxwell, January 5, 1984 3:15 pm
Rick Beach, April 3, 1985 6:46:16 pm PST
Types
Packed: TYPE = BasicTime.GMT; -- RECORD[LONG CARDINAL]
PackedSeconds:
TYPE =
RECORD[
LONG
CARDINAL];
Packed represents the time which is t-gmtEpoch seconds after midnight, 1 January 1968, the time chosen as the epoch or beginning of the Pilot time standard. Packed times should be compared directly only for equality; to find which of two Packed times comes first, convert each to PackedSeconds compare the result. However, if t2 is a gmt known to occur after t1, then t2-t1 is the seconds between t1 and t2. If t is a Packed time, then Packed[t+60] is the Packed time one minute after t.
PackedSeconds represents the number of seconds elapsed since the gmtEpoch. To convert between Packed and PackedSeconds, use the procedures PackedToSeconds and SecondsToPacked defined below.
Both Packed and PackedSeconds have associated printprocs for easier debugging.
Seconds: TYPE = LONG CARDINAL; -- for convenience and readability
defaultTime: Packed;
All procedures that accept a Packed time as an argument treat defaultTime as meaning now, i.e. the current time. Note however that Packed.Now[] # defaultTime.
Precision:
TYPE = {years, months, days, hours, minutes, seconds, unspecified};
Describes the precision of the result returned by SmartPack, and Parse, and is used to specify the precision of the result returned by Adjust.
Procedures
Now: PROCEDURE RETURNS [time: Packed] = INLINE { RETURN[BasicTime.Now[]]; };
PackedToSeconds:
PROCEDURE [time: Packed ← defaultTime]
RETURNS[PackedSeconds] =
INLINE {
RETURN[[BasicTime.Period[BasicTime.earliestGMT, IF time = defaultTime THEN Now[] ELSE time]]];
};
SecondsToPacked:
PROCEDURE [seconds: PackedSeconds]
RETURNS[time: Packed] =
INLINE {
RETURN[BasicTime.Update[BasicTime.earliestGMT, seconds]];
};
MakeRope:
PROCEDURE [
time: Packed ← defaultTime,
precision: Precision ← minutes,
includeDayOfWeek:
BOOL ←
FALSE,
useAMPM:
BOOL ←
TRUE
]
RETURNS[value: Rope.
ROPE];
defaulting all arguments produces a rope identical to that produced by the Tioga BasicTime command, e.g. April 29, 1983 4:16 pm.
If includeDayOfWeek then the same time would produce Friday, April 29, 1983 4:16 pm.
precision determines how accurately to represent the time, e.g. if precision = days, then the same time would produce April 29, 1983.
If useAMPM is FALSE, then 24 hour notation is used, i.e. the same time would produce April 29, 1983 16:16.
SmartPack:
PROCEDURE [
year: [0..2050] ← 0,
month: MonthOfYear ← unspecified,
day: [0..daysPerMonth] ← 0,
hour: [0..hoursPerDay] ← hoursPerDay,
minute: [0..minutesPerHour] ← minutesPerHour,
second: [0..secondsPerMinute] ← secondsPerMinute,
zone:
INT ←
LAST[
INT],
secondsThisYear:
INT ←
LAST[
INT],
daysThisYear: [0..daysPerYear] ← daysPerYear,
weekday: DayOfWeek ← unspecified,
baseTime: Packed ← defaultTime]
RETURNS [time: Packed, precision: Precision];
precision is determined by which arguments were specified.
SmartPack accepts a partial specification of a time and fills in the missing information assuming that the desired time refers to the earliest point after baseTime which satisfies the arguments specified. It is designed to be used to compute times corresponding to English phrases that contain the word "at" or "on". For example:
SmartPack[hour: 11, minute: 30]
means "at 11:30" today, i.e. if it is earlier than 11:30 now, otherwise 11:30 tomorrow. Precision is in minutes.
SmartPack[month: February, day: 16]
means "on February 16", i.e. 12:00AM of next February 16. Precision is in days.
SmartPack[weekDay: Thursday, hour: 16]
means "on Thursday, 4PM", i.e. two days from now, if today is Tuesday, six days from now if today is Friday, and seven days from now if today is Thursday and it is later than 4PM, otherwise, today if today is Thursday and it is earlier than 4pm. Precision is in hours.
Note: if both weekday and day are specified, then they must agree or else Error[overConstrained] is raised.
SmartPack[weekday: Tuesday, baseTime: SmartPack[month: November, day: 1].time]
means first Tuesday after first day in November, i.e. election day
SmartPack[weekday: Thursday, baseTime: SmartPack[month: November, day: 21].time]
means first Thursday after November 21, i.e. ThanksGiving.
Note: if arguments of two different precisions are specified, then values for all of the intervening precisions must also be specified or else an error is raised. For example, SmartPack[year: 1983, day: 14], or SmartPack[month: January, hour: 11] are illegal and raise Error[tooVague].
Adjust:
PROCEDURE [
years:
INT ←
LAST[
INT],
months:
INT ←
LAST[
INT],
days:
INT ←
LAST[
INT],
hours:
INT ←
LAST[
INT],
minutes:
INT ←
LAST[
INT],
seconds:
INT ←
LAST[
INT],
baseTime: Packed ← defaultTime,
precisionOfResult: Precision ← unspecified
-- unspecified means result should be precision of smallest specified argument.
]
RETURNS [time: Packed, precision: Precision];
Adjust is used for specifying a desired time in terms of a base time and an interval (positive or negative) from that time. It is designed to be used to compute times corresponding to English phrases that contain the word "in". For example
Adjust[hours: 11, minutes: 30]
means in eleven hours and thirty minutes from now.
Adjust[months: 1, days: 3]
means in one month and three days from now.
Note that for many situations, the effect of Adjust can be obtained by simply adding the appropriate seconds to the baseTime. However, "in one day" cannot be computed by simply adding 24 hours because of possibility of changeover to/from daylight saving time. Similarly, "in one month and three days" requires knowing something about how many days in that month. This is the reason for the existence of Adjust.
The precision argument is used to specify the precision of the result. The resulting time is truncated (not rounded) to the corresponding precision. For example, if it is now April 28, 1983 11:20 am, Adjust[months: 1, days: 3] is May 31, 1983 12:00am, i.e. precision = days, whereas Adjust[months: 1, days: 3, precisionOfResult: minutes] is May 31, 1983 11:20am, precision = minutes.
SmartPack[hour: 16, baseTime: Adjust[months: 1, days: 3].time]
means One month and three days from now at 4PM
Adjust[days: -7, hours: 2, baseTime: SmartPack[month: May, weekday: Sunday].time]
last sunday in April, 2AM, i.e. daylight savings time begins.
Note: Adjust will never raise an error. In particular, Adjusting from a longer month to a shorter month is handled by truncating, i.e. one month from May 31 is June 30, one month from January 29, 30 or 31 is the last day in February. Similarly, one year from February 29 is February 28.
Parse:
PROCEDURE [rope: Rope.
ROPE, baseTime: Packed ← defaultTime, search:
BOOL ←
TRUE]
RETURNS [time: Packed, precision: Precision, start, length:
NAT];
Parse performs the function of DateAndTime.Parse, i.e. parses the input string and returns a GMT time according to the Pilot standard. Parse recognizes a variety of forms, e.g. "April 29, 1983 8:54 pm", "29-Apr-83 20:54:03 PDT", "4/29/83 8 54", etc.
In addition to parsing complete dates, Parse also recognizes a variety of phrases that specify times in conjunction with SmartPack and Adjust, such as "Thursday, 4PM", "in 15 minutes", "Tomorrow at noon", "a month from Tuesday", "a week before May 2", etc.
If the input can't be reasonably interpreted as a date, Parse raises the error Unintelligible with an appropraite error code. If the input contains additional material at the beginning, e.g. "last edited by: Teitelman on: April 26, 1983 2:23 pm", and search = TRUE, then Parse will search until it finds what looks like the beginning of a date. However, once it starts on a date, any errors raised by Pack, SmartPack, or Adjust will be caught and converted into the error Unintelligible.
If Parse is successful, the start and length return values indicates the index of the first character in the date, and the number of characters in the date, i.e. start + length is the index of the first character in r that the parser did not examine.