-- file: TimeExtras.mesa, last edit:
-- Bruce, March 16, 1979 6:10 PM
-- HGM, July 31, 1980 2:43 AM

-- Copyright Xerox Corporation 1979, 1980

DIRECTORY
String USING [
InvalidNumber, StringBoundsFault,
StringToNumber, AppendChar, EquivalentSubString, UpperCase, SubStringDescriptor],
Time USING [Pack, Unpacked, Invalid],
TimeExtraDefs;

TimeExtras: PROGRAM
IMPORTS String, Time
EXPORTS TimeExtraDefs =
BEGIN

Empty: PROCEDURE [s: STRING] RETURNS [BOOLEAN] =
BEGIN RETURN [s = NIL OR s.length = 0] END;

EquivalentChar: PUBLIC PROCEDURE [c1, c2: CHARACTER] RETURNS [BOOLEAN] =
BEGIN RETURN [String.UpperCase[c1]=String.UpperCase[c2]] END;

GetToken: PROCEDURE [storage: STRING, s: STRING, c: CARDINAL]
RETURNS [is: CARDINAL] =
BEGIN
ch: CHARACTER;
FOR is ← c, is+1 UNTIL is >= s.length DO
SELECT String.UpperCase[ch ← s[is]] FROM
IN [’A..’Z], IN [’0..’9] =>
String.AppendChar[storage, ch];
’:, ’- => EXIT; -- terminator
’ => IF ~Empty[storage] THEN EXIT; --terminating blank
ENDCASE;
ENDLOOP;
RETURN[is + 1];
END;

PackedTimeFromString: PUBLIC PROCEDURE [s: STRING]
RETURNS [t: LONG CARDINAL] =
BEGIN
-- string format must be: bDD-MMM-YYbbHH:MM:SSbbZZTb
t ← DoIt[s !String.InvalidNumber, String.StringBoundsFault, Time.Invalid =>
BEGIN t ← 0; CONTINUE END]
END;

DoIt: PROCEDURE [s: STRING]
RETURNS [t: LONG CARDINAL] =
BEGIN

Get: PROCEDURE = BEGIN s1.length ← 0; nextChar ← GetToken[s1, s, nextChar] END;

GetNumber: PROCEDURE RETURNS [CARDINAL] =
BEGIN
Get[];
RETURN[String.StringToNumber[s1, 10]];
END;

m: String.SubStringDescriptor ← [
base: "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"L, offset: NULL, length: 3];
s1: STRING ← [3];
month: String.SubStringDescriptor ← [base: s1, offset: 0, length: NULL];
time: Time.Unpacked ← [0,0,0,0,0,0,0,8,FALSE];
nextChar: CARDINAL ← 0;
i: CARDINAL;
packIt: BOOLEAN ← TRUE;

IF Empty[s] THEN RETURN[0];
time.day ← GetNumber[];
Get[];
month.length ← s1.length;
FOR i IN [0..12) DO
m.offset ← i*3;
IF String.EquivalentSubString[@month, @m] THEN
BEGIN time.month ← i; EXIT END;
ENDLOOP;
time.year ← GetNumber[]; time.year ← time.year + 1900;
time.hour ← GetNumber[];
time.minute ← GetNumber[];
time.second ← GetNumber[];
Get[];
IF s1.length # 0 THEN
BEGIN
zones: PACKED ARRAY [5..8] OF CHARACTER = [’E,’C,’M,’P];
FOR i IN [5..8] DO
IF EquivalentChar[s1[0], zones[i]] THEN
BEGIN time.zone ← i; EXIT END;
REPEAT FINISHED => time.zone ← 0; -- GMT
ENDLOOP;
time.dst ← EquivalentChar[s1[1],’D];
packIt ← FALSE;
END;
t ← Time.Pack[time, packIt]
END;

END.