<> DIRECTORY Rope USING [ROPE], System USING [gmtEpoch, SecondsSinceEpoch, GreenwichMeanTime], Time USING [Current] ; Tempus: CEDAR DEFINITIONS IMPORTS Time, System = BEGIN <> Packed: TYPE = System.GreenwichMeanTime; -- RECORD[LONG CARDINAL] PackedSeconds: TYPE = RECORD[LONG CARDINAL]; <> <> <> Seconds: TYPE = LONG CARDINAL; -- for convenience and readability defaultTime: Packed = System.gmtEpoch; <> Unpacked: TYPE = RECORD [ year: [0..2050], -- base year is 1968 month: MonthOfYear, day: [0..daysPerMonth], -- first day of month = 1. hour: [0..hoursPerDay], minute: [0..minutesPerHour], second: [0..secondsPerMinute], zone: INT, -- delta in minutes, e.g. 60 corresponds to one zone east of here. Values > ABS[720] are outofbounds and give errors when passed to Pack <<>> <<-- from here on down is redundant information. It is ignored by Pack.>> dst: BOOLEAN, weekday: DayOfWeek, secondsThisYear: INT, -- [0..secondsPerYear]. Values > secondsPerYear are outofbounds and give errors when passed to Pack daysThisYear: [0..daysPerYear] ]; <<>> <> secondsPerMinute: INT = 60; minutesPerHour: INT = 60; hoursPerDay: INT = 24; daysPerMonth: INT = 31; monthsPerYear: INT = 12; daysPerYear: INT = 366; secondsPerYear: INT = secondsPerMinute*minutesPerHour*hoursPerDay*daysPerYear; daysPerWeek: INT = 7; DayOfWeek: TYPE = {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday, unspecified}; MonthOfYear: TYPE = {January, February, March, April, May, June, July, August, September, October, November, December, unspecified}; Precision: TYPE = {years, months, days, hours, minutes, seconds, unspecified}; <> <> Current: PROCEDURE RETURNS [time: Packed] = TRUSTED INLINE { RETURN[Time.Current[]]; }; PackedToSeconds: PROCEDURE [time: Packed _ defaultTime] RETURNS[PackedSeconds] = INLINE { RETURN[[System.SecondsSinceEpoch[IF time = defaultTime THEN Current[] ELSE time]]]; }; SecondsToPacked: PROCEDURE [seconds: PackedSeconds] RETURNS[time: Packed] = INLINE { RETURN[[seconds + System.gmtEpoch]]; }; Unpack: PROCEDURE [time: Packed _ defaultTime] RETURNS [unpacked: Unpacked]; Pack: PROCEDURE [unpacked: Unpacked] RETURNS [time: Packed]; <> MakeRope: PROCEDURE [ time: Packed _ defaultTime, precision: Precision _ minutes, includeDayOfWeek: BOOL _ FALSE, useAMPM: BOOL _ TRUE ] RETURNS[value: Rope.ROPE]; <> <> <> <> 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. <> <> << means "at 11:30" today, i.e. if it is earlier than 11:30 now, otherwise 11:30 tomorrow. Precision is in minutes.>> <> <> <> <> <> <> <> <> <> <> 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]; <> <> << means in eleven hours and thirty minutes from now.>> <> << means in one month and three days from now.>> <> <> <> <> <> <> <> Parse: PROCEDURE [rope: Rope.ROPE, baseTime: Packed _ defaultTime, search: BOOL _ TRUE] RETURNS [time: Packed, precision: Precision, start, length: NAT]; <> <> <> <> <> Error: ERROR [ec: ErrorCode]; ErrorCode: TYPE = { invalid, <> overConstrained, <> tooVague, nothingSpecified, <> notImplemented <> }; Unintelligible: ERROR [rope: Rope.ROPE, vicinity: INT, ec: ErrorCode]; <> END.