(* Copyright 2016, 2018 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . *) MODULE DateTime; IMPORT KOSAPI; CONST ERR* = -7.0E5; PROCEDURE Encode*(Year, Month, Day, Hour, Min, Sec: INTEGER): REAL; VAR d, i: INTEGER; M: ARRAY 14 OF CHAR; Res: REAL; BEGIN Res := ERR; IF (Year >= 1) & (Year <= 9999) & (Month >= 1) & (Month <= 12) & (Day >= 1) & (Day <= 31) & (Hour >= 0) & (Hour <= 23) & (Min >= 0) & (Min <= 59) & (Sec >= 0) & (Sec <= 59) THEN M := "_303232332323"; IF (Year MOD 4 = 0) & (Year MOD 100 # 0) OR (Year MOD 400 = 0) THEN M[2] := "1" END; IF Day <= ORD(M[Month]) - ORD("0") + 28 THEN DEC(Year); d := Year * 365 + (Year DIV 4) - (Year DIV 100) + (Year DIV 400) + Day - 693594; FOR i := 1 TO Month - 1 DO d := d + ORD(M[i]) - ORD("0") + 28 END; Res := FLT(d) + FLT(Hour * 3600000 + Min * 60000 + Sec * 1000) / 86400000.0 END END RETURN Res END Encode; PROCEDURE Decode*(Date: REAL; VAR Year, Month, Day, Hour, Min, Sec: INTEGER): BOOLEAN; VAR Res, flag: BOOLEAN; d, t, i: INTEGER; M: ARRAY 14 OF CHAR; PROCEDURE MonthDay(n: INTEGER; VAR d, Month: INTEGER; M: ARRAY OF CHAR): BOOLEAN; VAR Res: BOOLEAN; BEGIN Res := FALSE; IF d > ORD(M[n]) - ORD("0") + 28 THEN d := d - ORD(M[n]) + ORD("0") - 28; INC(Month); Res := TRUE END RETURN Res END MonthDay; BEGIN IF (Date >= -693593.0) & (Date < 2958466.0) THEN d := FLOOR(Date); t := FLOOR((Date - FLT(d)) * 86400000.0); d := d + 693593; Year := 1; Month := 1; WHILE d > 0 DO d := d - 365 - ORD((Year MOD 4 = 0) & (Year MOD 100 # 0) OR (Year MOD 400 = 0)); INC(Year) END; IF d < 0 THEN DEC(Year); d := d + 365 + ORD((Year MOD 4 = 0) & (Year MOD 100 # 0) OR (Year MOD 400 = 0)) END; INC(d); M := "_303232332323"; IF (Year MOD 4 = 0) & (Year MOD 100 # 0) OR (Year MOD 400 = 0) THEN M[2] := "1" END; i := 1; flag := TRUE; WHILE flag & (i <= 12) DO flag := MonthDay(i, d, Month, M); INC(i) END; Day := d; Hour := t DIV 3600000; t := t MOD 3600000; Min := t DIV 60000; t := t MOD 60000; Sec := t DIV 1000; Res := TRUE ELSE Res := FALSE END RETURN Res END Decode; PROCEDURE Now*(VAR Year, Month, Day, Hour, Min, Sec, Msec: INTEGER); VAR date, time: INTEGER; BEGIN date := KOSAPI.sysfunc1(29); time := KOSAPI.sysfunc1(3); Year := date MOD 16; date := date DIV 16; Year := (date MOD 16) * 10 + Year; date := date DIV 16; Month := date MOD 16; date := date DIV 16; Month := (date MOD 16) * 10 + Month; date := date DIV 16; Day := date MOD 16; date := date DIV 16; Day := (date MOD 16) * 10 + Day; date := date DIV 16; Hour := time MOD 16; time := time DIV 16; Hour := (time MOD 16) * 10 + Hour; time := time DIV 16; Min := time MOD 16; time := time DIV 16; Min := (time MOD 16) * 10 + Min; time := time DIV 16; Sec := time MOD 16; time := time DIV 16; Sec := (time MOD 16) * 10 + Sec; time := time DIV 16; Year := Year + 2000; Msec := 0 END Now; END DateTime.