Subversion Repositories Kolibri OS

Rev

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

  1. (*
  2.     BSD 2-Clause License
  3.  
  4.     Copyright (c) 2019, Anton Krotov
  5.     All rights reserved.
  6. *)
  7.  
  8. MODULE DateTime;
  9.  
  10. IMPORT WINAPI;
  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 init;
  120. VAR
  121.     day, year, month, i: INTEGER;
  122.     Months: ARRAY 13 OF INTEGER;
  123.  
  124. BEGIN
  125.     Months[1] := 31; Months[2] := 28; Months[3] := 31; Months[4] := 30;
  126.     Months[5] := 31; Months[6] := 30; Months[7] := 31; Months[8] := 31;
  127.     Months[9] := 30; Months[10] := 31; Months[11] := 30; Months[12] := 31;
  128.  
  129.     day := 0;
  130.     year := 1;
  131.     month := 1;
  132.     i := 0;
  133.  
  134.     WHILE year <= 10000 DO
  135.         DateTable[i][0] := day;
  136.         DateTable[i][1] := year;
  137.         DateTable[i][2] := month;
  138.         INC(day, Months[month]);
  139.         IF (month = 2) & ((year MOD 4 = 0) & (year MOD 100 # 0) OR (year MOD 400 = 0)) THEN
  140.             INC(day)
  141.         END;
  142.         INC(month);
  143.         IF month > 12 THEN
  144.             month := 1;
  145.             INC(year)
  146.         END;
  147.         INC(i)
  148.     END;
  149.  
  150.     MonthsTable[1][0] := 0;
  151.     FOR i := 2 TO 12 DO
  152.         MonthsTable[i][0] := MonthsTable[i - 1][0] + Months[i - 1]
  153.     END;
  154.  
  155.     FOR i := 1 TO 12 DO
  156.         MonthsTable[i][2] := Months[i]
  157.     END;
  158.  
  159.     Months[2] := 29;
  160.     MonthsTable[1][1] := 0;
  161.     FOR i := 2 TO 12 DO
  162.         MonthsTable[i][1] := MonthsTable[i - 1][1] + Months[i - 1]
  163.     END;
  164.  
  165.     FOR i := 1 TO 12 DO
  166.         MonthsTable[i][3] := Months[i]
  167.     END
  168.  
  169. END init;
  170.  
  171.  
  172. BEGIN
  173.     init
  174. END DateTime.