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