-- file: TimeExtraImpl.mesa, last edit: -- AlHall, 9-Jul-82 14:28:40 -- Bruce, March 16, 1979 6:10 PM -- HGM, January 27, 1981 5:35 PM -- Hankins Klamath update (time zone chagne) 24-Jul-84 14:54:10 -- Copyright Xerox Corporation 1979, 1980 DIRECTORY String USING [ InvalidNumber, StringBoundsFault, StringToNumber, AppendChar, EquivalentSubString, UpperCase, SubStringDescriptor], System USING [gmtEpoch], Time USING [Pack, Packed, Unpacked, Invalid], TimeExtra USING []; TimeExtraImpl: PROGRAM IMPORTS String, Time EXPORTS TimeExtra = BEGIN Empty: PROCEDURE [s: LONG 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: LONG STRING, s: LONG 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: LONG STRING] RETURNS [t: Time.Packed] = BEGIN -- string format must be: bDD-MMM-YYbbHH:MM:SSbbZZTb t ← DoIt[ s ! String.InvalidNumber, String.StringBoundsFault, Time.Invalid => BEGIN t ← System.gmtEpoch; CONTINUE END] END; DoIt: PROCEDURE [s: LONG STRING] RETURNS [t: Time.Packed] = 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: LONG STRING ← [3]; month: String.SubStringDescriptor ← [base: s1, offset: 0, length: NULL]; time: Time.Unpacked ← [ year: 0, month: 0, day: 0, hour: 0, minute: 0, second: 0, weekday: 0, zone: [direction: west, zone: 8, zoneMinutes: 0, beginDST: 0, endDST: 0], dst: FALSE]; nextChar: CARDINAL ← 0; i: CARDINAL; packIt: BOOLEAN ← TRUE; IF Empty[s] THEN RETURN[System.gmtEpoch]; 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.zone ← i; EXIT END; REPEAT FINISHED => time.zone.zone ← 0; -- GMT ENDLOOP; time.dst ← EquivalentChar[s1[1], 'D]; packIt ← FALSE; END; t ← Time.Pack[time, packIt] END; END.