-- file: TimeExtraImpl.mesa, last edit: -- Bruce, March 16, 1979 6:10 PM -- HGM, January 27, 1981 5:35 PM -- 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: 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: 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: 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: 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[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 _ 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.