Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2019-2020, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE DateTime;
  9.  
  10. IMPORT WINAPI, SYSTEM;
  11.  
  12.  
  13. CONST
  14.  
  15.     ERR* = -7.0E5;
  16.  
  17.  
  18. VAR
  19.  
  20.     DateTable: ARRAY 120000, 3 OF INTEGER;
  21.     MonthsTable: ARRAY 13, 4 OF INTEGER;
  22.  
  23.  
  24. PROCEDURE Encode* (Year, Month, Day, Hour, Min, Sec, MSec: INTEGER): REAL;
  25. VAR
  26.     d, bis: INTEGER;
  27.     res: REAL;
  28.  
  29. BEGIN
  30.     res := ERR;
  31.     IF (Year >= 1) & (Year <= 9999) & (Month >= 1) & (Month <= 12) &
  32.         (Day >= 1) & (Day <= 31) & (Hour >= 0) & (Hour <= 23) &
  33.         (Min >= 0) & (Min <= 59) & (Sec >= 0) & (Sec <= 59) &
  34.         (MSec >= 0) & (MSec <= 999) THEN
  35.  
  36.         bis := ORD((Year MOD 4 = 0) & (Year MOD 100 # 0) OR (Year MOD 400 = 0));
  37.  
  38.         IF Day <= MonthsTable[Month][2 + bis] THEN
  39.             DEC(Year);
  40.             d := Year * 365 + (Year DIV 4) - (Year DIV 100) + (Year DIV 400) +
  41.                 MonthsTable[Month][bis] + Day - 693594;
  42.             res := FLT(d) + FLT(Hour * 3600000 + Min * 60000 + Sec * 1000 + MSec) / 86400000.0
  43.         END
  44.     END
  45.     RETURN res
  46. END Encode;
  47.  
  48.  
  49. PROCEDURE Decode* (Date: REAL; VAR Year, Month, Day, Hour, Min, Sec, MSec: INTEGER): BOOLEAN;
  50. VAR
  51.     res: BOOLEAN;
  52.     d, t: INTEGER;
  53.     L, R, M: INTEGER;
  54.  
  55. BEGIN
  56.     res := (Date >= -693593.0) & (Date < 2958466.0);
  57.     IF res THEN
  58.         d := FLOOR(Date);
  59.         t := FLOOR((Date - FLT(d)) * 86400000.0);
  60.         INC(d, 693593);
  61.  
  62.         L := 0;
  63.         R := LEN(DateTable) - 1;
  64.         M := (L + R) DIV 2;
  65.  
  66.         WHILE R - L > 1 DO
  67.             IF d > DateTable[M][0] THEN
  68.                 L := M;
  69.                 M := (L + R) DIV 2
  70.             ELSIF d < DateTable[M][0] THEN
  71.                 R := M;
  72.                 M := (L + R) DIV 2
  73.             ELSE
  74.                 L := M;
  75.                 R := M
  76.             END
  77.         END;
  78.  
  79.         Year  := DateTable[L][1];
  80.         Month := DateTable[L][2];
  81.         Day   := d - DateTable[L][0] + 1;
  82.  
  83.         Hour := t DIV 3600000; t := t MOD 3600000;
  84.         Min  := t DIV 60000;   t := t MOD 60000;
  85.         Sec  := t DIV 1000;
  86.         MSec := t MOD 1000
  87.     END
  88.  
  89.     RETURN res
  90. END Decode;
  91.  
  92.  
  93. PROCEDURE Now* (VAR Year, Month, Day, Hour, Min, Sec, MSec: INTEGER);
  94. VAR
  95.     T: WINAPI.TSystemTime;
  96.  
  97. BEGIN
  98.     WINAPI.GetLocalTime(T);
  99.     Year  := ORD(T.Year);
  100.     Month := ORD(T.Month);
  101.     Day   := ORD(T.Day);
  102.     Hour  := ORD(T.Hour);
  103.     Min   := ORD(T.Min);
  104.     Sec   := ORD(T.Sec);
  105.     MSec  := ORD(T.MSec)
  106. END Now;
  107.  
  108.  
  109. PROCEDURE NowEncode* (): REAL;
  110. VAR
  111.     Year, Month, Day, Hour, Min, Sec, MSec: INTEGER;
  112.  
  113. BEGIN
  114.     Now(Year, Month, Day, Hour, Min, Sec, MSec)
  115.     RETURN Encode(Year, Month, Day, Hour, Min, Sec, MSec)
  116. END NowEncode;
  117.  
  118.  
  119. PROCEDURE NowUnixTime* (): INTEGER;
  120.     RETURN WINAPI.time(0)
  121. END NowUnixTime;
  122.  
  123.  
  124. PROCEDURE UnixTime* (Year, Month, Day, Hour, Min, Sec: INTEGER): INTEGER;
  125. VAR
  126.     t: WINAPI.tm;
  127.  
  128. BEGIN
  129.     DEC(Year, 1900);
  130.     DEC(Month);
  131.     SYSTEM.GET(SYSTEM.ADR(Sec),   t.sec);
  132.     SYSTEM.GET(SYSTEM.ADR(Min),   t.min);
  133.     SYSTEM.GET(SYSTEM.ADR(Hour),  t.hour);
  134.     SYSTEM.GET(SYSTEM.ADR(Day),   t.mday);
  135.     SYSTEM.GET(SYSTEM.ADR(Month), t.mon);
  136.     SYSTEM.GET(SYSTEM.ADR(Year),  t.year);
  137.  
  138.     RETURN WINAPI.mktime(t)
  139. END UnixTime;
  140.  
  141.  
  142. PROCEDURE init;
  143. VAR
  144.     day, year, month, i: INTEGER;
  145.     Months: ARRAY 13 OF INTEGER;
  146.  
  147. BEGIN
  148.     Months[1] := 31; Months[2] := 28; Months[3] := 31; Months[4] := 30;
  149.     Months[5] := 31; Months[6] := 30; Months[7] := 31; Months[8] := 31;
  150.     Months[9] := 30; Months[10] := 31; Months[11] := 30; Months[12] := 31;
  151.  
  152.     day := 0;
  153.     year := 1;
  154.     month := 1;
  155.     i := 0;
  156.  
  157.     WHILE year <= 10000 DO
  158.         DateTable[i][0] := day;
  159.         DateTable[i][1] := year;
  160.         DateTable[i][2] := month;
  161.         INC(day, Months[month]);
  162.         IF (month = 2) & ((year MOD 4 = 0) & (year MOD 100 # 0) OR (year MOD 400 = 0)) THEN
  163.             INC(day)
  164.         END;
  165.         INC(month);
  166.         IF month > 12 THEN
  167.             month := 1;
  168.             INC(year)
  169.         END;
  170.         INC(i)
  171.     END;
  172.  
  173.     MonthsTable[1][0] := 0;
  174.     FOR i := 2 TO 12 DO
  175.         MonthsTable[i][0] := MonthsTable[i - 1][0] + Months[i - 1]
  176.     END;
  177.  
  178.     FOR i := 1 TO 12 DO
  179.         MonthsTable[i][2] := Months[i]
  180.     END;
  181.  
  182.     Months[2] := 29;
  183.     MonthsTable[1][1] := 0;
  184.     FOR i := 2 TO 12 DO
  185.         MonthsTable[i][1] := MonthsTable[i - 1][1] + Months[i - 1]
  186.     END;
  187.  
  188.     FOR i := 1 TO 12 DO
  189.         MonthsTable[i][3] := Months[i]
  190.     END
  191.  
  192. END init;
  193.  
  194.  
  195. BEGIN
  196.     init
  197. END DateTime.