xref: /reactos/sdk/lib/atl/atltime.h (revision 9c544a55)
1 // PROJECT:        ReactOS ATL CTime, CFileTime, CTimeSpan, CFileTimeSpan
2 // LICENSE:        Public Domain
3 // PURPOSE:        Provides compatibility to Microsoft ATL
4 // PROGRAMMERS:    Benedikt Freisen
5 
6 #ifndef __ATLTIME_H__
7 #define __ATLTIME_H__
8 
9 // WARNING: Untested code
10 
11 #pragma once
12 
13 #include <atlcore.h>
14 #include <windows.h>
15 #include <atlstr.h>
16 #include <time.h>
17 #include <oledb.h>
18 
19 namespace ATL
20 {
21 
22 class CTimeSpan
23 {
24     __time64_t m_nSpan;
25 public:
26     CTimeSpan() noexcept
27     {
28         // leave uninitialized
29     }
30 
31     CTimeSpan(__time64_t time) noexcept
32     {
33         m_nSpan = time;
34     }
35 
36     CTimeSpan(LONG lDays, int nHours, int nMins, int nSecs) noexcept
37     {
38         ATLASSERT(lDays >= 0 && nHours >= 0 && nHours <= 23 && nMins >= 0 && nMins <= 59 && nSecs >= 0 && nSecs <= 59);
39         m_nSpan = ((((LONGLONG)lDays) * 24 + nHours) * 60 + nMins) * 60 + nSecs;
40     }
41 
42     CString Format(LPCSTR pFormat) const
43     {
44         struct tm time;
45         _localtime64_s(&time, &m_nSpan);
46         CStringA strTime;
47         strftime(strTime.GetBuffer(256), 256, pFormat, &time);
48         strTime.ReleaseBuffer();
49         return CString(strTime);
50     }
51 
52     CString Format(LPCTSTR pszFormat) const
53     {
54         struct tm time;
55         _localtime64_s(&time, &m_nSpan);
56         CString strTime;
57 #ifdef UNICODE
58         wcsftime(strTime.GetBuffer(256), 256, pszFormat, &time);
59 #else
60         strftime(strTime.GetBuffer(256), 256, pszFormat, &time);
61 #endif
62         strTime.ReleaseBuffer();
63         return strTime;
64     }
65 
66     CString Format(UINT nID) const
67     {
68         struct tm time;
69         _localtime64_s(&time, &m_nSpan);
70         CString strFormat;
71         strFormat.LoadString(nID);
72         CString strTime;
73 #ifdef UNICODE
74         wcsftime(strTime.GetBuffer(256), 256, strFormat, &time);
75 #else
76         strftime(strTime.GetBuffer(256), 256, strFormat, &time);
77 #endif
78         strTime.ReleaseBuffer();
79         return strTime;
80     }
81 
82     LONGLONG GetTotalHours() const noexcept
83     {
84         return m_nSpan / 60 / 60;
85     }
86 
87     LONGLONG GetTotalMinutes() const noexcept
88     {
89         return m_nSpan / 60;
90     }
91 
92     LONGLONG GetTotalSeconds() const noexcept
93     {
94         return m_nSpan;
95     }
96 
97     LONGLONG GetDays() const noexcept
98     {
99         return m_nSpan / 60 / 60 / 24;
100     }
101 
102     LONG GetHours() const noexcept
103     {
104         return GetTotalHours() - GetDays() * 24;
105     }
106 
107     LONG GetMinutes() const noexcept
108     {
109         return GetTotalMinutes() - GetTotalHours() * 60;
110     }
111 
112     LONG GetSeconds() const noexcept
113     {
114         return GetTotalSeconds() - GetTotalMinutes() * 60;
115     }
116 
117     __time64_t GetTimeSpan() const noexcept
118     {
119         return m_nSpan;
120     }
121 
122 //     CArchive& Serialize64(CArchive& ar)  // MFC only
123 //     {
124 //         // TODO
125 //     }
126 
127 };
128 
129 class CTime
130 {
131     __time64_t m_nTime;
132 public:
133     CTime() noexcept
134     {
135         // leave uninitialized
136     }
137 
138     CTime(__time64_t time) noexcept
139     {
140         m_nTime = time;
141     }
142 
143     CTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec, int nDST = -1)
144     {
145         struct tm time;
146         time.tm_year = nYear;
147         time.tm_mon = nMonth;
148         time.tm_mday = nDay;
149         time.tm_hour = nHour;
150         time.tm_min = nMin;
151         time.tm_sec = nSec;
152         time.tm_isdst = nDST;
153         m_nTime = _mktime64(&time);
154     }
155 
156     CTime(WORD wDosDate, WORD wDosTime, int nDST = -1)
157     {
158         FILETIME ft;
159         DosDateTimeToFileTime(wDosDate, wDosTime, &ft);
160         SYSTEMTIME st;
161         FileTimeToSystemTime(&ft, &st);
162         struct tm time;
163         time.tm_year = st.wYear;
164         time.tm_mon = st.wMonth;
165         time.tm_wday = st.wDayOfWeek;
166         time.tm_hour = st.wHour;
167         time.tm_min = st.wMinute;
168         time.tm_sec = st.wSecond;
169         time.tm_isdst = nDST;
170         m_nTime = _mktime64(&time);
171     }
172 
173     CTime(const SYSTEMTIME& st, int nDST = -1) noexcept
174     {
175         struct tm time;
176         time.tm_year = st.wYear;
177         time.tm_mon = st.wMonth;
178         time.tm_wday = st.wDayOfWeek;
179         time.tm_hour = st.wHour;
180         time.tm_min = st.wMinute;
181         time.tm_sec = st.wSecond;
182         time.tm_isdst = nDST;
183         m_nTime = _mktime64(&time);
184     }
185 
186     CTime(const FILETIME& ft, int nDST = -1)
187     {
188         SYSTEMTIME st;
189         FileTimeToSystemTime(&ft, &st);
190         struct tm time;
191         time.tm_year = st.wYear;
192         time.tm_mon = st.wMonth;
193         time.tm_wday = st.wDayOfWeek;
194         time.tm_hour = st.wHour;
195         time.tm_min = st.wMinute;
196         time.tm_sec = st.wSecond;
197         time.tm_isdst = nDST;
198         m_nTime = _mktime64(&time);
199     }
200 
201     CTime(const DBTIMESTAMP& dbts, int nDST = -1) noexcept
202     {
203         struct tm time;
204         time.tm_year = dbts.year;
205         time.tm_mon = dbts.month;
206         time.tm_hour = dbts.hour;
207         time.tm_min = dbts.minute;
208         time.tm_sec = dbts.second;
209         time.tm_isdst = nDST;
210         m_nTime = _mktime64(&time);
211     }
212 
213     CString Format(LPCTSTR pszFormat) const
214     {
215         struct tm time;
216         _localtime64_s(&time, &m_nTime);
217         CString strTime;
218 #ifdef UNICODE
219         wcsftime(strTime.GetBuffer(256), 256, pszFormat, &time);
220 #else
221         strftime(strTime.GetBuffer(256), 256, pszFormat, &time);
222 #endif
223         strTime.ReleaseBuffer();
224         return strTime;
225     }
226 
227     CString Format(UINT nFormatID) const
228     {
229         struct tm time;
230         _localtime64_s(&time, &m_nTime);
231         CString strFormat;
232         strFormat.LoadString(nFormatID);
233         CString strTime;
234 #ifdef UNICODE
235         wcsftime(strTime.GetBuffer(256), 256, strFormat, &time);
236 #else
237         strftime(strTime.GetBuffer(256), 256, strFormat, &time);
238 #endif
239         strTime.ReleaseBuffer();
240         return strTime;
241     }
242 
243     CString FormatGmt(LPCTSTR pszFormat) const
244     {
245         struct tm time;
246         _gmtime64_s(&time, &m_nTime);
247         CString strTime;
248 #ifdef UNICODE
249         wcsftime(strTime.GetBuffer(256), 256, pszFormat, &time);
250 #else
251         strftime(strTime.GetBuffer(256), 256, pszFormat, &time);
252 #endif
253         strTime.ReleaseBuffer();
254         return strTime;
255     }
256 
257     CString FormatGmt(UINT nFormatID) const
258     {
259         struct tm time;
260         _gmtime64_s(&time, &m_nTime);
261         CString strFormat;
262         strFormat.LoadString(nFormatID);
263         CString strTime;
264 #ifdef UNICODE
265         wcsftime(strTime.GetBuffer(256), 256, strFormat, &time);
266 #else
267         strftime(strTime.GetBuffer(256), 256, strFormat, &time);
268 #endif
269         strTime.ReleaseBuffer();
270         return strTime;
271     }
272 
273     bool GetAsDBTIMESTAMP(DBTIMESTAMP& dbts) const noexcept
274     {
275         struct tm time;
276         _gmtime64_s(&time, &m_nTime);
277         dbts.year = time.tm_year;
278         dbts.month = time.tm_mon;
279         dbts.day = time.tm_mday;
280         dbts.hour = time.tm_hour;
281         dbts.minute = time.tm_min;
282         dbts.second = time.tm_sec;
283         dbts.fraction = 0;
284         return true;  // TODO: error handling?
285     }
286 
287     bool GetAsSystemTime(SYSTEMTIME& st) const noexcept
288     {
289         struct tm time;
290         _gmtime64_s(&time, &m_nTime);
291         st.wYear = time.tm_year;
292         st.wMonth = time.tm_mon;
293         st.wDayOfWeek = time.tm_wday;
294         st.wDay = time.tm_mday;
295         st.wHour = time.tm_hour;
296         st.wMinute = time.tm_min;
297         st.wSecond = time.tm_sec;
298         st.wMilliseconds = 0;
299         return true;  // TODO: error handling?
300     }
301 
302     static CTime WINAPI GetCurrentTime() noexcept
303     {
304         __time64_t time;
305         _time64(&time);
306         return CTime(time);
307     }
308 
309     int GetDay() const noexcept
310     {
311         struct tm time;
312         _localtime64_s(&time, &m_nTime);
313         return time.tm_mday;
314     }
315 
316     int GetDayOfWeek() const noexcept
317     {
318         struct tm time;
319         _localtime64_s(&time, &m_nTime);
320         return time.tm_wday;
321     }
322 
323     struct tm* GetGmtTm(struct tm* ptm) const
324     {
325         _gmtime64_s(ptm, &m_nTime);
326         return ptm;
327     }
328 
329     int GetHour() const noexcept
330     {
331         struct tm time;
332         _localtime64_s(&time, &m_nTime);
333         return time.tm_hour;
334     }
335 
336     struct tm* GetLocalTm(struct tm* ptm) const
337     {
338         _localtime64_s(ptm, &m_nTime);
339         return ptm;
340     }
341 
342     int GetMinute() const noexcept
343     {
344         struct tm time;
345         _localtime64_s(&time, &m_nTime);
346         return time.tm_min;
347     }
348 
349     int GetMonth() const noexcept
350     {
351         struct tm time;
352         _localtime64_s(&time, &m_nTime);
353         return time.tm_mon;
354     }
355 
356     int GetSecond() const noexcept
357     {
358         struct tm time;
359         _localtime64_s(&time, &m_nTime);
360         return time.tm_sec;
361     }
362 
363     __time64_t GetTime() const noexcept
364     {
365         return m_nTime;
366     }
367 
368     int GetYear()
369     {
370         struct tm time;
371         _localtime64_s(&time, &m_nTime);
372         return time.tm_year;
373     }
374 
375 //     CArchive& Serialize64(CArchive& ar)  // MFC only
376 //     {
377 //         // TODO
378 //     }
379 
380     CTime operator+(CTimeSpan timeSpan) const noexcept
381     {
382         return CTime(m_nTime + timeSpan.GetTimeSpan());
383     }
384 
385     CTime operator-(CTimeSpan timeSpan) const noexcept
386     {
387         return CTime(m_nTime - timeSpan.GetTimeSpan());
388     }
389 
390     CTimeSpan operator-(CTime time) const noexcept
391     {
392         return CTimeSpan(m_nTime - time.GetTime());
393     }
394 
395     CTime& operator+=(CTimeSpan span) noexcept
396     {
397         m_nTime += span.GetTimeSpan();
398         return *this;
399     }
400 
401     CTime& operator-=(CTimeSpan span) noexcept
402     {
403         m_nTime -= span.GetTimeSpan();
404         return *this;
405     }
406 
407     CTime& operator=(__time64_t time) noexcept
408     {
409         m_nTime = time;
410         return *this;
411     }
412 
413     bool operator==(CTime time) const noexcept
414     {
415         return m_nTime == time.GetTime();
416     }
417 
418     bool operator!=(CTime time) const noexcept
419     {
420         return m_nTime != time.GetTime();
421     }
422 
423     bool operator<(CTime time) const noexcept
424     {
425         return m_nTime < time.GetTime();
426     }
427 
428     bool operator>(CTime time) const noexcept
429     {
430         return m_nTime > time.GetTime();
431     }
432 
433     bool operator<=(CTime time) const noexcept
434     {
435         return m_nTime <= time.GetTime();
436     }
437 
438     bool operator>=(CTime time) const noexcept
439     {
440         return m_nTime >= time.GetTime();
441     }
442 
443 };
444 
445 class CFileTimeSpan
446 {
447     LONGLONG m_nSpan;
448 public:
449     CFileTimeSpan() noexcept
450     {
451         m_nSpan = 0;
452     }
453 
454     CFileTimeSpan(const CFileTimeSpan& span) noexcept
455     {
456         m_nSpan = span.GetTimeSpan();
457     }
458 
459     CFileTimeSpan(LONGLONG nSpan) noexcept
460     {
461         m_nSpan = nSpan;
462     }
463 
464     LONGLONG GetTimeSpan() const noexcept
465     {
466         return m_nSpan;
467     }
468 
469     void SetTimeSpan(LONGLONG nSpan) noexcept
470     {
471         m_nSpan = nSpan;
472     }
473 
474     CFileTimeSpan operator-(CFileTimeSpan span) const noexcept
475     {
476         return CFileTimeSpan(m_nSpan - span.GetTimeSpan());
477     }
478 
479     bool operator!=(CFileTimeSpan span) const noexcept
480     {
481         return m_nSpan != span.GetTimeSpan();
482     }
483 
484     CFileTimeSpan operator+(CFileTimeSpan span) const noexcept
485     {
486         return CFileTimeSpan(m_nSpan + span.GetTimeSpan());
487     }
488 
489     CFileTimeSpan& operator+=(CFileTimeSpan span) noexcept
490     {
491         m_nSpan += span.GetTimeSpan();
492         return *this;
493     }
494 
495     bool operator<(CFileTimeSpan span) const noexcept
496     {
497         return m_nSpan < span.GetTimeSpan();
498     }
499 
500     bool operator<=(CFileTimeSpan span) const noexcept
501     {
502         return m_nSpan <= span.GetTimeSpan();
503     }
504 
505     CFileTimeSpan& operator=(const CFileTimeSpan& span) noexcept
506     {
507         m_nSpan = span.GetTimeSpan();
508         return *this;
509     }
510 
511     CFileTimeSpan& operator-=(CFileTimeSpan span) noexcept
512     {
513         m_nSpan -= span.GetTimeSpan();
514         return *this;
515     }
516 
517     bool operator==(CFileTimeSpan span) const noexcept
518     {
519         return m_nSpan == span.GetTimeSpan();
520     }
521 
522     bool operator>(CFileTimeSpan span) const noexcept
523     {
524         return m_nSpan > span.GetTimeSpan();
525     }
526 
527     bool operator>=(CFileTimeSpan span) const noexcept
528     {
529         return m_nSpan >= span.GetTimeSpan();
530     }
531 
532 };
533 
534 class CFileTime : public FILETIME
535 {
536 public:
537     static const ULONGLONG Millisecond = 10000;
538     static const ULONGLONG Second = Millisecond * 1000;
539     static const ULONGLONG Minute = Second * 60;
540     static const ULONGLONG Hour = Minute * 60;
541     static const ULONGLONG Day = Hour * 24;
542     static const ULONGLONG Week = Day * 7;
543 
544     CFileTime() noexcept
545     {
546         this->dwLowDateTime = 0;
547         this->dwHighDateTime = 0;
548     }
549 
550     CFileTime(const FILETIME& ft) noexcept
551     {
552         this->dwLowDateTime = ft.dwLowDateTime;
553         this->dwHighDateTime = ft.dwHighDateTime;
554     }
555 
556     CFileTime(ULONGLONG nTime) noexcept
557     {
558         this->dwLowDateTime = (DWORD) nTime;
559         this->dwHighDateTime = nTime >> 32;
560     }
561 
562     static CFileTime GetCurrentTime() noexcept
563     {
564         FILETIME ft;
565         GetSystemTimeAsFileTime(&ft);
566         return CFileTime(ft);
567     }
568 
569     ULONGLONG GetTime() const noexcept
570     {
571         return ((ULONGLONG)this->dwLowDateTime) | (((ULONGLONG)this->dwHighDateTime) << 32);
572     }
573 
574     CFileTime LocalToUTC() const noexcept
575     {
576         FILETIME ft;
577         LocalFileTimeToFileTime(this, &ft);
578         return CFileTime(ft);
579     }
580 
581     void SetTime(ULONGLONG nTime) noexcept
582     {
583         this->dwLowDateTime = (DWORD) nTime;
584         this->dwHighDateTime = nTime >> 32;
585     }
586 
587     CFileTime UTCToLocal() const noexcept
588     {
589         FILETIME ft;
590         FileTimeToLocalFileTime(this, &ft);
591         return CFileTime(ft);
592     }
593 
594     CFileTime operator-(CFileTimeSpan span) const noexcept
595     {
596         return CFileTime(this->GetTime() - span.GetTimeSpan());
597     }
598 
599     CFileTimeSpan operator-(CFileTime ft) const noexcept
600     {
601         return CFileTimeSpan(this->GetTime() - ft.GetTime());
602     }
603 
604     bool operator!=(CFileTime ft) const noexcept
605     {
606         return this->GetTime() != ft.GetTime();
607     }
608 
609     CFileTime operator+(CFileTimeSpan span) const noexcept
610     {
611         return CFileTime(this->GetTime() + span.GetTimeSpan());
612     }
613 
614     CFileTime& operator+=(CFileTimeSpan span) noexcept
615     {
616         this->SetTime(this->GetTime() + span.GetTimeSpan());
617         return *this;
618     }
619 
620     bool operator<(CFileTime ft) const noexcept
621     {
622         return this->GetTime() < ft.GetTime();
623     }
624 
625     bool operator<=(CFileTime ft) const noexcept
626     {
627         return this->GetTime() <= ft.GetTime();
628     }
629 
630     CFileTime& operator=(const FILETIME& ft) noexcept
631     {
632         this->dwLowDateTime = ft.dwLowDateTime;
633         this->dwHighDateTime = ft.dwHighDateTime;
634         return *this;
635     }
636 
637     CFileTime& operator-=(CFileTimeSpan span) noexcept
638     {
639         this->SetTime(this->GetTime() - span.GetTimeSpan());
640         return *this;
641     }
642 
643     bool operator==(CFileTime ft) const noexcept
644     {
645         return this->GetTime() == ft.GetTime();
646     }
647 
648     bool operator>(CFileTime ft) const noexcept
649     {
650         return this->GetTime() > ft.GetTime();
651     }
652 
653     bool operator>=(CFileTime ft) const noexcept
654     {
655         return this->GetTime() >= ft.GetTime();
656     }
657 
658 };
659 
660 }  // namespace ATL
661 
662 #endif
663