Subversion Repositories Kolibri OS

Rev

Rev 7983 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7983 leency 1
(*
2
    BSD 2-Clause License
3
 
8097 maxcodehac 4
    Copyright (c) 2019-2020, Anton Krotov
7983 leency 5
    All rights reserved.
6
*)
7
 
8
MODULE DateTime;
9
 
8097 maxcodehac 10
IMPORT WINAPI, SYSTEM;
7983 leency 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
 
8097 maxcodehac 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
 
7983 leency 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.