Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
7983 leency 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.