Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1482 lines
32 KiB

  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 1996-2001 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Active Template Library Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Active Template Library product.
  10. #ifndef __ATLTIME_INL__
  11. #define __ATLTIME_INL__
  12. #pragma once
  13. #ifndef __ATLTIME_H__
  14. #error atltime.inl requires atltime.h to be included first
  15. #endif
  16. #include <math.h>
  17. namespace ATL
  18. {
  19. // Used only if these strings could not be found in resources.
  20. __declspec(selectany) const TCHAR *szInvalidDateTime = _T("Invalid DateTime");
  21. __declspec(selectany) const TCHAR *szInvalidDateTimeSpan = _T("Invalid DateTimeSpan");
  22. const int maxTimeBufferSize = 128;
  23. const long maxDaysInSpan = 3615897L;
  24. /////////////////////////////////////////////////////////////////////////////
  25. // CTimeSpan
  26. /////////////////////////////////////////////////////////////////////////////
  27. inline CTimeSpan::CTimeSpan() :
  28. m_timeSpan(0)
  29. {
  30. }
  31. inline CTimeSpan::CTimeSpan( __time64_t time ) :
  32. m_timeSpan( time )
  33. {
  34. }
  35. inline CTimeSpan::CTimeSpan(LONG lDays, int nHours, int nMins, int nSecs)
  36. {
  37. m_timeSpan = nSecs + 60* (nMins + 60* (nHours + __int64(24) * lDays));
  38. }
  39. inline LONGLONG CTimeSpan::GetDays() const
  40. {
  41. return( m_timeSpan/(24*3600) );
  42. }
  43. inline LONGLONG CTimeSpan::GetTotalHours() const
  44. {
  45. return( m_timeSpan/3600 );
  46. }
  47. inline LONG CTimeSpan::GetHours() const
  48. {
  49. return( LONG( GetTotalHours()-(GetDays()*24) ) );
  50. }
  51. inline LONGLONG CTimeSpan::GetTotalMinutes() const
  52. {
  53. return( m_timeSpan/60 );
  54. }
  55. inline LONG CTimeSpan::GetMinutes() const
  56. {
  57. return( LONG( GetTotalMinutes()-(GetTotalHours()*60) ) );
  58. }
  59. inline LONGLONG CTimeSpan::GetTotalSeconds() const
  60. {
  61. return( m_timeSpan );
  62. }
  63. inline LONG CTimeSpan::GetSeconds() const
  64. {
  65. return( LONG( GetTotalSeconds()-(GetTotalMinutes()*60) ) );
  66. }
  67. inline __time64_t CTimeSpan::GetTimeSpan() const
  68. {
  69. return( m_timeSpan );
  70. }
  71. inline CTimeSpan CTimeSpan::operator+( CTimeSpan span ) const
  72. {
  73. return( CTimeSpan( m_timeSpan+span.m_timeSpan ) );
  74. }
  75. inline CTimeSpan CTimeSpan::operator-( CTimeSpan span ) const
  76. {
  77. return( CTimeSpan( m_timeSpan-span.m_timeSpan ) );
  78. }
  79. inline CTimeSpan& CTimeSpan::operator+=( CTimeSpan span )
  80. {
  81. m_timeSpan += span.m_timeSpan;
  82. return( *this );
  83. }
  84. inline CTimeSpan& CTimeSpan::operator-=( CTimeSpan span )
  85. {
  86. m_timeSpan -= span.m_timeSpan;
  87. return( *this );
  88. }
  89. inline bool CTimeSpan::operator==( CTimeSpan span ) const
  90. {
  91. return( m_timeSpan == span.m_timeSpan );
  92. }
  93. inline bool CTimeSpan::operator!=( CTimeSpan span ) const
  94. {
  95. return( m_timeSpan != span.m_timeSpan );
  96. }
  97. inline bool CTimeSpan::operator<( CTimeSpan span ) const
  98. {
  99. return( m_timeSpan < span.m_timeSpan );
  100. }
  101. inline bool CTimeSpan::operator>( CTimeSpan span ) const
  102. {
  103. return( m_timeSpan > span.m_timeSpan );
  104. }
  105. inline bool CTimeSpan::operator<=( CTimeSpan span ) const
  106. {
  107. return( m_timeSpan <= span.m_timeSpan );
  108. }
  109. inline bool CTimeSpan::operator>=( CTimeSpan span ) const
  110. {
  111. return( m_timeSpan >= span.m_timeSpan );
  112. }
  113. #ifndef _ATL_MIN_CRT
  114. inline CString CTimeSpan::Format(LPCTSTR pFormat) const
  115. // formatting timespans is a little trickier than formatting CTimes
  116. // * we are only interested in relative time formats, ie. it is illegal
  117. // to format anything dealing with absolute time (i.e. years, months,
  118. // day of week, day of year, timezones, ...)
  119. // * the only valid formats:
  120. // %D - # of days
  121. // %H - hour in 24 hour format
  122. // %M - minute (0-59)
  123. // %S - seconds (0-59)
  124. // %% - percent sign
  125. {
  126. TCHAR szBuffer[maxTimeBufferSize];
  127. TCHAR ch;
  128. LPTSTR pch = szBuffer;
  129. while ((ch = *pFormat++) != _T('\0'))
  130. {
  131. ATLASSERT(pch < &szBuffer[maxTimeBufferSize-1]);
  132. if (ch == _T('%'))
  133. {
  134. switch (ch = *pFormat++)
  135. {
  136. default:
  137. ATLASSERT(FALSE); // probably a bad format character
  138. break;
  139. case '%':
  140. *pch++ = ch;
  141. break;
  142. case 'D':
  143. pch += _stprintf(pch, _T("%I64d"), GetDays());
  144. break;
  145. case 'H':
  146. pch += _stprintf(pch, _T("%02ld"), GetHours());
  147. break;
  148. case 'M':
  149. pch += _stprintf(pch, _T("%02ld"), GetMinutes());
  150. break;
  151. case 'S':
  152. pch += _stprintf(pch, _T("%02ld"), GetSeconds());
  153. break;
  154. }
  155. }
  156. else
  157. {
  158. *pch++ = ch;
  159. if (_istlead(ch))
  160. {
  161. ATLASSERT(pch < &szBuffer[maxTimeBufferSize]);
  162. *pch++ = *pFormat++;
  163. }
  164. }
  165. }
  166. *pch = '\0';
  167. return szBuffer;
  168. }
  169. inline CString CTimeSpan::Format(UINT nFormatID) const
  170. {
  171. CString strFormat;
  172. ATLVERIFY(strFormat.LoadString(nFormatID));
  173. return Format(strFormat);
  174. }
  175. #endif // !_ATL_MIN_CRT
  176. #if defined(_AFX) && defined(_UNICODE)
  177. inline CString CTimeSpan::Format(LPCSTR pFormat) const
  178. {
  179. return Format(CString(pFormat));
  180. }
  181. #endif
  182. /////////////////////////////////////////////////////////////////////////////
  183. // CTime
  184. /////////////////////////////////////////////////////////////////////////////
  185. inline CTime CTime::GetCurrentTime()
  186. {
  187. return( CTime( ::_time64( NULL ) ) );
  188. }
  189. inline CTime::CTime() :
  190. m_time(0)
  191. {
  192. }
  193. inline CTime::CTime( __time64_t time ) :
  194. m_time( time )
  195. {
  196. }
  197. inline CTime::CTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec,
  198. int nDST)
  199. {
  200. struct tm atm;
  201. atm.tm_sec = nSec;
  202. atm.tm_min = nMin;
  203. atm.tm_hour = nHour;
  204. ATLASSERT(nDay >= 1 && nDay <= 31);
  205. atm.tm_mday = nDay;
  206. ATLASSERT(nMonth >= 1 && nMonth <= 12);
  207. atm.tm_mon = nMonth - 1; // tm_mon is 0 based
  208. ATLASSERT(nYear >= 1900);
  209. atm.tm_year = nYear - 1900; // tm_year is 1900 based
  210. atm.tm_isdst = nDST;
  211. m_time = _mktime64(&atm);
  212. ATLASSERT(m_time != -1); // indicates an illegal input time
  213. }
  214. inline CTime::CTime(WORD wDosDate, WORD wDosTime, int nDST)
  215. {
  216. struct tm atm;
  217. atm.tm_sec = (wDosTime & ~0xFFE0) << 1;
  218. atm.tm_min = (wDosTime & ~0xF800) >> 5;
  219. atm.tm_hour = wDosTime >> 11;
  220. atm.tm_mday = wDosDate & ~0xFFE0;
  221. atm.tm_mon = ((wDosDate & ~0xFE00) >> 5) - 1;
  222. atm.tm_year = (wDosDate >> 9) + 80;
  223. atm.tm_isdst = nDST;
  224. m_time = _mktime64(&atm);
  225. ATLASSERT(m_time != -1); // indicates an illegal input time
  226. }
  227. inline CTime::CTime(const SYSTEMTIME& sysTime, int nDST)
  228. {
  229. if (sysTime.wYear < 1900)
  230. {
  231. __time64_t time0 = 0L;
  232. CTime timeT(time0);
  233. *this = timeT;
  234. }
  235. else
  236. {
  237. CTime timeT(
  238. (int)sysTime.wYear, (int)sysTime.wMonth, (int)sysTime.wDay,
  239. (int)sysTime.wHour, (int)sysTime.wMinute, (int)sysTime.wSecond,
  240. nDST);
  241. *this = timeT;
  242. }
  243. }
  244. inline CTime::CTime(const FILETIME& fileTime, int nDST)
  245. {
  246. // first convert file time (UTC time) to local time
  247. FILETIME localTime;
  248. if (!FileTimeToLocalFileTime(&fileTime, &localTime))
  249. {
  250. m_time = 0;
  251. return;
  252. }
  253. // then convert that time to system time
  254. SYSTEMTIME sysTime;
  255. if (!FileTimeToSystemTime(&localTime, &sysTime))
  256. {
  257. m_time = 0;
  258. return;
  259. }
  260. // then convert the system time to a time_t (C-runtime local time)
  261. CTime timeT(sysTime, nDST);
  262. *this = timeT;
  263. }
  264. #ifdef __oledb_h__
  265. inline CTime::CTime( const DBTIMESTAMP& dbts, int nDST )
  266. {
  267. struct tm atm;
  268. atm.tm_sec = dbts.second;
  269. atm.tm_min = dbts.minute;
  270. atm.tm_hour = dbts.hour;
  271. atm.tm_mday = dbts.day;
  272. atm.tm_mon = dbts.month - 1; // tm_mon is 0 based
  273. ATLASSERT(dbts.year >= 1900);
  274. atm.tm_year = dbts.year - 1900; // tm_year is 1900 based
  275. atm.tm_isdst = nDST;
  276. m_time = _mktime64(&atm);
  277. ATLASSERT(m_time != -1); // indicates an illegal input time
  278. }
  279. #endif
  280. inline CTime& CTime::operator=( __time64_t time )
  281. {
  282. m_time = time;
  283. return( *this );
  284. }
  285. inline CTime& CTime::operator+=( CTimeSpan span )
  286. {
  287. m_time += span.GetTimeSpan();
  288. return( *this );
  289. }
  290. inline CTime& CTime::operator-=( CTimeSpan span )
  291. {
  292. m_time -= span.GetTimeSpan();
  293. return( *this );
  294. }
  295. inline CTimeSpan CTime::operator-( CTime time ) const
  296. {
  297. return( CTimeSpan( m_time-time.m_time ) );
  298. }
  299. inline CTime CTime::operator-( CTimeSpan span ) const
  300. {
  301. return( CTime( m_time-span.GetTimeSpan() ) );
  302. }
  303. inline CTime CTime::operator+( CTimeSpan span ) const
  304. {
  305. return( CTime( m_time+span.GetTimeSpan() ) );
  306. }
  307. inline bool CTime::operator==( CTime time ) const
  308. {
  309. return( m_time == time.m_time );
  310. }
  311. inline bool CTime::operator!=( CTime time ) const
  312. {
  313. return( m_time != time.m_time );
  314. }
  315. inline bool CTime::operator<( CTime time ) const
  316. {
  317. return( m_time < time.m_time );
  318. }
  319. inline bool CTime::operator>( CTime time ) const
  320. {
  321. return( m_time > time.m_time );
  322. }
  323. inline bool CTime::operator<=( CTime time ) const
  324. {
  325. return( m_time <= time.m_time );
  326. }
  327. inline bool CTime::operator>=( CTime time ) const
  328. {
  329. return( m_time >= time.m_time );
  330. }
  331. inline struct tm* CTime::GetGmtTm(struct tm* ptm) const
  332. {
  333. if (ptm != NULL)
  334. {
  335. *ptm = *_gmtime64(&m_time);
  336. return ptm;
  337. }
  338. else
  339. return _gmtime64(&m_time);
  340. }
  341. inline struct tm* CTime::GetLocalTm(struct tm* ptm) const
  342. {
  343. if (ptm != NULL)
  344. {
  345. struct tm* ptmTemp = _localtime64(&m_time);
  346. if (ptmTemp == NULL)
  347. return NULL; // indicates the m_time was not initialized!
  348. *ptm = *ptmTemp;
  349. return ptm;
  350. }
  351. else
  352. return _localtime64(&m_time);
  353. }
  354. inline bool CTime::GetAsSystemTime(SYSTEMTIME& timeDest) const
  355. {
  356. struct tm* ptm = GetLocalTm(NULL);
  357. if (!ptm)
  358. return false;
  359. timeDest.wYear = (WORD) (1900 + ptm->tm_year);
  360. timeDest.wMonth = (WORD) (1 + ptm->tm_mon);
  361. timeDest.wDayOfWeek = (WORD) ptm->tm_wday;
  362. timeDest.wDay = (WORD) ptm->tm_mday;
  363. timeDest.wHour = (WORD) ptm->tm_hour;
  364. timeDest.wMinute = (WORD) ptm->tm_min;
  365. timeDest.wSecond = (WORD) ptm->tm_sec;
  366. timeDest.wMilliseconds = 0;
  367. return true;
  368. }
  369. #ifdef __oledb_h__
  370. inline bool CTime::GetAsDBTIMESTAMP( DBTIMESTAMP& dbts ) const
  371. {
  372. struct tm* ptm = GetLocalTm(NULL);
  373. if (!ptm)
  374. return false;
  375. dbts.year = (SHORT) (1900 + ptm->tm_year);
  376. dbts.month = (USHORT) (1 + ptm->tm_mon);
  377. dbts.day = (USHORT) ptm->tm_mday;
  378. dbts.hour = (USHORT) ptm->tm_hour;
  379. dbts.minute = (USHORT) ptm->tm_min;
  380. dbts.second = (USHORT) ptm->tm_sec;
  381. dbts.fraction = 0;
  382. return true;
  383. }
  384. #endif
  385. inline __time64_t CTime::GetTime() const
  386. {
  387. return( m_time );
  388. }
  389. inline int CTime::GetYear() const
  390. {
  391. return( GetLocalTm()->tm_year+1900 );
  392. }
  393. inline int CTime::GetMonth() const
  394. {
  395. return( GetLocalTm()->tm_mon+1 );
  396. }
  397. inline int CTime::GetDay() const
  398. {
  399. return( GetLocalTm()->tm_mday );
  400. }
  401. inline int CTime::GetHour() const
  402. {
  403. return( GetLocalTm()->tm_hour );
  404. }
  405. inline int CTime::GetMinute() const
  406. {
  407. return( GetLocalTm()->tm_min );
  408. }
  409. inline int CTime::GetSecond() const
  410. {
  411. return( GetLocalTm()->tm_sec );
  412. }
  413. inline int CTime::GetDayOfWeek() const
  414. {
  415. return( GetLocalTm()->tm_wday+1 );
  416. }
  417. #ifndef _ATL_MIN_CRT
  418. inline CString CTime::Format(LPCTSTR pFormat) const
  419. {
  420. TCHAR szBuffer[maxTimeBufferSize];
  421. struct tm* ptmTemp = _localtime64(&m_time);
  422. if (ptmTemp == NULL ||
  423. !_tcsftime(szBuffer, maxTimeBufferSize, pFormat, ptmTemp))
  424. szBuffer[0] = '\0';
  425. return szBuffer;
  426. }
  427. inline CString CTime::FormatGmt(LPCTSTR pFormat) const
  428. {
  429. TCHAR szBuffer[maxTimeBufferSize];
  430. struct tm* ptmTemp = _gmtime64(&m_time);
  431. if (ptmTemp == NULL ||
  432. !_tcsftime(szBuffer, maxTimeBufferSize, pFormat, ptmTemp))
  433. szBuffer[0] = '\0';
  434. return szBuffer;
  435. }
  436. inline CString CTime::Format(UINT nFormatID) const
  437. {
  438. CString strFormat;
  439. ATLVERIFY(strFormat.LoadString(nFormatID));
  440. return Format(strFormat);
  441. }
  442. inline CString CTime::FormatGmt(UINT nFormatID) const
  443. {
  444. CString strFormat;
  445. ATLVERIFY(strFormat.LoadString(nFormatID));
  446. return FormatGmt(strFormat);
  447. }
  448. #endif // !_ATL_MIN_CRT
  449. #if defined (_AFX) && defined(_UNICODE)
  450. inline CString CTime::Format(LPCSTR pFormat) const
  451. {
  452. return Format(CString(pFormat));
  453. }
  454. inline CString CTime::FormatGmt(LPCSTR pFormat) const
  455. {
  456. return FormatGmt(CString(pFormat));
  457. }
  458. #endif // _AFX && _UNICODE
  459. /////////////////////////////////////////////////////////////////////////////
  460. // COleDateTimeSpan
  461. /////////////////////////////////////////////////////////////////////////////
  462. inline COleDateTimeSpan::COleDateTimeSpan() : m_span(0), m_status(valid)
  463. {
  464. }
  465. inline COleDateTimeSpan::COleDateTimeSpan(double dblSpanSrc) : m_span(dblSpanSrc), m_status(valid)
  466. {
  467. CheckRange();
  468. }
  469. inline COleDateTimeSpan::COleDateTimeSpan(LONG lDays, int nHours, int nMins, int nSecs)
  470. {
  471. SetDateTimeSpan(lDays, nHours, nMins, nSecs);
  472. }
  473. inline void COleDateTimeSpan::SetStatus(DateTimeSpanStatus status)
  474. {
  475. m_status = status;
  476. }
  477. inline COleDateTimeSpan::DateTimeSpanStatus COleDateTimeSpan::GetStatus() const
  478. {
  479. return m_status;
  480. }
  481. __declspec(selectany) const double
  482. COleDateTimeSpan::OLE_DATETIME_HALFSECOND =
  483. 1.0 / (2.0 * (60.0 * 60.0 * 24.0));
  484. inline double COleDateTimeSpan::GetTotalDays() const
  485. {
  486. ATLASSERT(GetStatus() == valid);
  487. return LONG(m_span + (m_span < 0 ?
  488. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND));
  489. }
  490. inline double COleDateTimeSpan::GetTotalHours() const
  491. {
  492. ATLASSERT(GetStatus() == valid);
  493. return LONG((m_span + (m_span < 0 ?
  494. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND)) * 24);
  495. }
  496. inline double COleDateTimeSpan::GetTotalMinutes() const
  497. {
  498. ATLASSERT(GetStatus() == valid);
  499. return LONG((m_span + (m_span < 0 ?
  500. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND)) * (24 * 60));
  501. }
  502. inline double COleDateTimeSpan::GetTotalSeconds() const
  503. {
  504. ATLASSERT(GetStatus() == valid);
  505. return LONG((m_span + (m_span < 0 ?
  506. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND)) * (24 * 60 * 60));
  507. }
  508. inline LONG COleDateTimeSpan::GetDays() const
  509. {
  510. ATLASSERT(GetStatus() == valid);
  511. return LONG(m_span);
  512. }
  513. inline LONG COleDateTimeSpan::GetHours() const
  514. {
  515. return LONG(GetTotalHours()) % 24;
  516. }
  517. inline LONG COleDateTimeSpan::GetMinutes() const
  518. {
  519. return LONG(GetTotalMinutes()) % 60;
  520. }
  521. inline LONG COleDateTimeSpan::GetSeconds() const
  522. {
  523. return LONG(GetTotalSeconds()) % 60;
  524. }
  525. inline COleDateTimeSpan& COleDateTimeSpan::operator=(double dblSpanSrc)
  526. {
  527. m_span = dblSpanSrc;
  528. m_status = valid;
  529. CheckRange();
  530. return *this;
  531. }
  532. inline bool COleDateTimeSpan::operator==(const COleDateTimeSpan& dateSpan) const
  533. {
  534. ATLASSERT(GetStatus() == valid);
  535. ATLASSERT(dateSpan.GetStatus() == valid);
  536. return (m_status == dateSpan.m_status &&
  537. m_span == dateSpan.m_span);
  538. }
  539. inline bool COleDateTimeSpan::operator!=(const COleDateTimeSpan& dateSpan) const
  540. {
  541. ATLASSERT(GetStatus() == valid);
  542. ATLASSERT(dateSpan.GetStatus() == valid);
  543. return (m_status != dateSpan.m_status ||
  544. m_span != dateSpan.m_span);
  545. }
  546. inline bool COleDateTimeSpan::operator<(const COleDateTimeSpan& dateSpan) const
  547. {
  548. ATLASSERT(GetStatus() == valid);
  549. ATLASSERT(dateSpan.GetStatus() == valid);
  550. return m_span < dateSpan.m_span;
  551. }
  552. inline bool COleDateTimeSpan::operator>(const COleDateTimeSpan& dateSpan) const
  553. {
  554. ATLASSERT(GetStatus() == valid);
  555. ATLASSERT(dateSpan.GetStatus() == valid);
  556. return m_span > dateSpan.m_span;
  557. }
  558. inline bool COleDateTimeSpan::operator<=(const COleDateTimeSpan& dateSpan) const
  559. {
  560. ATLASSERT(GetStatus() == valid);
  561. ATLASSERT(dateSpan.GetStatus() == valid);
  562. return m_span <= dateSpan.m_span;
  563. }
  564. inline bool COleDateTimeSpan::operator>=(const COleDateTimeSpan& dateSpan) const
  565. {
  566. ATLASSERT(GetStatus() == valid);
  567. ATLASSERT(dateSpan.GetStatus() == valid);
  568. return m_span >= dateSpan.m_span;
  569. }
  570. inline COleDateTimeSpan COleDateTimeSpan::operator+(const COleDateTimeSpan& dateSpan) const
  571. {
  572. COleDateTimeSpan dateSpanTemp;
  573. // If either operand Null, result Null
  574. if (GetStatus() == null || dateSpan.GetStatus() == null)
  575. {
  576. dateSpanTemp.SetStatus(null);
  577. return dateSpanTemp;
  578. }
  579. // If either operand Invalid, result Invalid
  580. if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
  581. {
  582. dateSpanTemp.SetStatus(invalid);
  583. return dateSpanTemp;
  584. }
  585. // Add spans and validate within legal range
  586. dateSpanTemp.m_span = m_span + dateSpan.m_span;
  587. dateSpanTemp.CheckRange();
  588. return dateSpanTemp;
  589. }
  590. inline COleDateTimeSpan COleDateTimeSpan::operator-(const COleDateTimeSpan& dateSpan) const
  591. {
  592. COleDateTimeSpan dateSpanTemp;
  593. // If either operand Null, result Null
  594. if (GetStatus() == null || dateSpan.GetStatus() == null)
  595. {
  596. dateSpanTemp.SetStatus(null);
  597. return dateSpanTemp;
  598. }
  599. // If either operand Invalid, result Invalid
  600. if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
  601. {
  602. dateSpanTemp.SetStatus(invalid);
  603. return dateSpanTemp;
  604. }
  605. // Subtract spans and validate within legal range
  606. dateSpanTemp.m_span = m_span - dateSpan.m_span;
  607. dateSpanTemp.CheckRange();
  608. return dateSpanTemp;
  609. }
  610. inline COleDateTimeSpan& COleDateTimeSpan::operator+=(const COleDateTimeSpan dateSpan)
  611. {
  612. ATLASSERT(GetStatus() == valid);
  613. ATLASSERT(dateSpan.GetStatus() == valid);
  614. *this = *this + dateSpan;
  615. CheckRange();
  616. return *this;
  617. }
  618. inline COleDateTimeSpan& COleDateTimeSpan::operator-=(const COleDateTimeSpan dateSpan)
  619. {
  620. ATLASSERT(GetStatus() == valid);
  621. ATLASSERT(dateSpan.GetStatus() == valid);
  622. *this = *this - dateSpan;
  623. CheckRange();
  624. return *this;
  625. }
  626. inline COleDateTimeSpan COleDateTimeSpan::operator-() const
  627. {
  628. return -this->m_span;
  629. }
  630. inline COleDateTimeSpan::operator double() const
  631. {
  632. return m_span;
  633. }
  634. inline void COleDateTimeSpan::SetDateTimeSpan(LONG lDays, int nHours, int nMins, int nSecs)
  635. {
  636. // Set date span by breaking into fractional days (all input ranges valid)
  637. m_span = lDays + ((double)nHours)/24 + ((double)nMins)/(24*60) +
  638. ((double)nSecs)/(24*60*60);
  639. m_status = valid;
  640. CheckRange();
  641. }
  642. #ifndef _ATL_MIN_CRT
  643. inline CString COleDateTimeSpan::Format(LPCTSTR pFormat) const
  644. {
  645. // If null, return empty string
  646. if (GetStatus() == null)
  647. return _T("");
  648. CTimeSpan tmp(GetDays(), GetHours(), GetMinutes(), GetSeconds());
  649. return tmp.Format(pFormat);
  650. }
  651. inline CString COleDateTimeSpan::Format(UINT nFormatID) const
  652. {
  653. CString strFormat;
  654. ATLVERIFY(strFormat.LoadString(nFormatID));
  655. return Format(strFormat);
  656. }
  657. #endif // !_ATL_MIN_CRT
  658. inline void COleDateTimeSpan::CheckRange()
  659. {
  660. if(m_span < -maxDaysInSpan || m_span > maxDaysInSpan)
  661. m_status = invalid;
  662. }
  663. /////////////////////////////////////////////////////////////////////////////
  664. // COleDateTime
  665. /////////////////////////////////////////////////////////////////////////////
  666. inline COleDateTime COleDateTime::GetCurrentTime()
  667. {
  668. return COleDateTime(::_time64(NULL));
  669. }
  670. inline COleDateTime::COleDateTime() :
  671. m_dt( 0 ), m_status(valid)
  672. {
  673. }
  674. inline COleDateTime::COleDateTime( const VARIANT& varSrc ) :
  675. m_dt( 0 ), m_status(valid)
  676. {
  677. *this = varSrc;
  678. }
  679. inline COleDateTime::COleDateTime( DATE dtSrc ) :
  680. m_dt( dtSrc ), m_status(valid)
  681. {
  682. }
  683. #ifndef _WIN64
  684. inline COleDateTime::COleDateTime( time_t timeSrc) :
  685. m_dt( 0 ), m_status(valid)
  686. {
  687. *this = timeSrc;
  688. }
  689. #endif
  690. inline COleDateTime::COleDateTime( __time64_t timeSrc ) :
  691. m_dt( 0 ), m_status(valid)
  692. {
  693. *this = timeSrc;
  694. }
  695. inline COleDateTime::COleDateTime( const SYSTEMTIME& systimeSrc ) :
  696. m_dt( 0 ), m_status(valid)
  697. {
  698. *this = systimeSrc;
  699. }
  700. inline COleDateTime::COleDateTime( const FILETIME& filetimeSrc ) :
  701. m_dt( 0 ), m_status(valid)
  702. {
  703. *this = filetimeSrc;
  704. }
  705. inline COleDateTime::COleDateTime(int nYear, int nMonth, int nDay,
  706. int nHour, int nMin, int nSec)
  707. {
  708. SetDateTime(nYear, nMonth, nDay, nHour, nMin, nSec);
  709. }
  710. inline COleDateTime::COleDateTime(WORD wDosDate, WORD wDosTime)
  711. {
  712. m_status = ::DosDateTimeToVariantTime(wDosDate, wDosTime, &m_dt) ?
  713. valid : invalid;
  714. }
  715. inline void COleDateTime::SetStatus(DateTimeStatus status)
  716. {
  717. m_status = status;
  718. }
  719. inline COleDateTime::DateTimeStatus COleDateTime::GetStatus() const
  720. {
  721. return m_status;
  722. }
  723. inline bool COleDateTime::GetAsSystemTime(SYSTEMTIME& sysTime) const
  724. {
  725. return GetStatus() == valid && ::VariantTimeToSystemTime(m_dt, &sysTime);
  726. }
  727. inline bool COleDateTime::GetAsUDATE(UDATE &udate) const
  728. {
  729. return SUCCEEDED(::VarUdateFromDate(m_dt, 0, &udate));
  730. }
  731. inline int COleDateTime::GetYear() const
  732. {
  733. SYSTEMTIME st;
  734. return GetAsSystemTime(st) ? st.wYear : error;
  735. }
  736. inline int COleDateTime::GetMonth() const
  737. {
  738. SYSTEMTIME st;
  739. return GetAsSystemTime(st) ? st.wMonth : error;
  740. }
  741. inline int COleDateTime::GetDay() const
  742. {
  743. SYSTEMTIME st;
  744. return GetAsSystemTime(st) ? st.wDay : error;
  745. }
  746. inline int COleDateTime::GetHour() const
  747. {
  748. SYSTEMTIME st;
  749. return GetAsSystemTime(st) ? st.wHour : error;
  750. }
  751. inline int COleDateTime::GetMinute() const
  752. {
  753. SYSTEMTIME st;
  754. return GetAsSystemTime(st) ? st.wMinute : error;
  755. }
  756. inline int COleDateTime::GetSecond() const
  757. {
  758. SYSTEMTIME st;
  759. return GetAsSystemTime(st) ? st.wSecond : error;
  760. }
  761. inline int COleDateTime::GetDayOfWeek() const
  762. {
  763. SYSTEMTIME st;
  764. return GetAsSystemTime(st) ? st.wDayOfWeek + 1 : error;
  765. }
  766. inline int COleDateTime::GetDayOfYear() const
  767. {
  768. UDATE udate;
  769. return GetAsUDATE(udate) ? udate.wDayOfYear : error;
  770. }
  771. inline COleDateTime& COleDateTime::operator=(const VARIANT& varSrc)
  772. {
  773. if (varSrc.vt != VT_DATE)
  774. {
  775. VARIANT varDest;
  776. varDest.vt = VT_EMPTY;
  777. if(SUCCEEDED(::VariantChangeType(&varDest, const_cast<VARIANT *>(&varSrc), 0, VT_DATE)))
  778. {
  779. m_dt = varDest.date;
  780. m_status = valid;
  781. }
  782. else
  783. m_status = invalid;
  784. }
  785. else
  786. {
  787. m_dt = varSrc.date;
  788. m_status = valid;
  789. }
  790. return *this;
  791. }
  792. inline COleDateTime& COleDateTime::operator=(DATE dtSrc)
  793. {
  794. m_dt = dtSrc;
  795. m_status = valid;
  796. return *this;
  797. }
  798. #ifndef _WIN64
  799. inline COleDateTime& COleDateTime::operator=(const time_t& timeSrc)
  800. {
  801. return operator=(static_cast<__time64_t>(timeSrc));
  802. }
  803. #endif // _WIN64
  804. inline COleDateTime& COleDateTime::operator=(const __time64_t& timeSrc)
  805. {
  806. SYSTEMTIME st;
  807. CTime tmp(timeSrc);
  808. m_status = tmp.GetAsSystemTime(st) &&
  809. ::SystemTimeToVariantTime(&st, &m_dt) ? valid : invalid;
  810. return *this;
  811. }
  812. inline COleDateTime &COleDateTime::operator=(const SYSTEMTIME &systimeSrc)
  813. {
  814. m_status = ::SystemTimeToVariantTime(const_cast<SYSTEMTIME *>(&systimeSrc), &m_dt) ?
  815. valid : invalid;
  816. return *this;
  817. }
  818. inline COleDateTime &COleDateTime::operator=(const FILETIME &filetimeSrc)
  819. {
  820. SYSTEMTIME st;
  821. m_status = ::FileTimeToSystemTime(&filetimeSrc, &st) &&
  822. ::SystemTimeToVariantTime(&st, &m_dt) ?
  823. valid : invalid;
  824. return *this;
  825. }
  826. inline COleDateTime &COleDateTime::operator=(const UDATE &udate)
  827. {
  828. m_status = (S_OK == VarDateFromUdate((UDATE*)&udate, 0, &m_dt)) ? valid : invalid;
  829. return *this;
  830. }
  831. inline bool COleDateTime::operator==( const COleDateTime& date ) const
  832. {
  833. ATLASSERT(GetStatus() == valid);
  834. ATLASSERT(date.GetStatus() == valid);
  835. return( m_dt == date.m_dt );
  836. }
  837. inline bool COleDateTime::operator!=( const COleDateTime& date ) const
  838. {
  839. ATLASSERT(GetStatus() == valid);
  840. ATLASSERT(date.GetStatus() == valid);
  841. return( m_dt != date.m_dt );
  842. }
  843. inline bool COleDateTime::operator<( const COleDateTime& date ) const
  844. {
  845. ATLASSERT(GetStatus() == valid);
  846. ATLASSERT(date.GetStatus() == valid);
  847. return( DoubleFromDate( m_dt ) < DoubleFromDate( date.m_dt ) );
  848. }
  849. inline bool COleDateTime::operator>( const COleDateTime& date ) const
  850. {
  851. ATLASSERT(GetStatus() == valid);
  852. ATLASSERT(date.GetStatus() == valid);
  853. return( DoubleFromDate( m_dt ) > DoubleFromDate( date.m_dt ) );
  854. }
  855. inline bool COleDateTime::operator<=( const COleDateTime& date ) const
  856. {
  857. ATLASSERT(GetStatus() == valid);
  858. ATLASSERT(date.GetStatus() == valid);
  859. return( DoubleFromDate( m_dt ) <= DoubleFromDate( date.m_dt ) );
  860. }
  861. inline bool COleDateTime::operator>=( const COleDateTime& date ) const
  862. {
  863. ATLASSERT(GetStatus() == valid);
  864. ATLASSERT(date.GetStatus() == valid);
  865. return( DoubleFromDate( m_dt ) >= DoubleFromDate( date.m_dt ) );
  866. }
  867. inline COleDateTime COleDateTime::operator+( COleDateTimeSpan dateSpan ) const
  868. {
  869. ATLASSERT(GetStatus() == valid);
  870. ATLASSERT(dateSpan.GetStatus() == valid);
  871. return( COleDateTime( DateFromDouble( DoubleFromDate( m_dt )+(double)dateSpan ) ) );
  872. }
  873. inline COleDateTime COleDateTime::operator-( COleDateTimeSpan dateSpan ) const
  874. {
  875. ATLASSERT(GetStatus() == valid);
  876. ATLASSERT(dateSpan.GetStatus() == valid);
  877. return( COleDateTime( DateFromDouble( DoubleFromDate( m_dt )-(double)dateSpan ) ) );
  878. }
  879. inline COleDateTime& COleDateTime::operator+=( COleDateTimeSpan dateSpan )
  880. {
  881. ATLASSERT(GetStatus() == valid);
  882. ATLASSERT(dateSpan.GetStatus() == valid);
  883. m_dt = DateFromDouble( DoubleFromDate( m_dt )+(double)dateSpan );
  884. return( *this );
  885. }
  886. inline COleDateTime& COleDateTime::operator-=( COleDateTimeSpan dateSpan )
  887. {
  888. ATLASSERT(GetStatus() == valid);
  889. ATLASSERT(dateSpan.GetStatus() == valid);
  890. m_dt = DateFromDouble( DoubleFromDate( m_dt )-(double)dateSpan );
  891. return( *this );
  892. }
  893. inline COleDateTimeSpan COleDateTime::operator-(const COleDateTime& date) const
  894. {
  895. ATLASSERT(GetStatus() == valid);
  896. ATLASSERT(date.GetStatus() == valid);
  897. return DoubleFromDate(m_dt) - DoubleFromDate(date.m_dt);
  898. }
  899. inline COleDateTime::operator DATE() const
  900. {
  901. ATLASSERT(GetStatus() == valid);
  902. return( m_dt );
  903. }
  904. inline int COleDateTime::SetDateTime(int nYear, int nMonth, int nDay,
  905. int nHour, int nMin, int nSec)
  906. {
  907. SYSTEMTIME st;
  908. ::ZeroMemory(&st, sizeof(SYSTEMTIME));
  909. st.wYear = WORD(nYear);
  910. st.wMonth = WORD(nMonth);
  911. st.wDay = WORD(nDay);
  912. st.wHour = WORD(nHour);
  913. st.wMinute = WORD(nMin);
  914. st.wSecond = WORD(nSec);
  915. return m_status = ::SystemTimeToVariantTime(&st, &m_dt) ? valid : invalid;
  916. }
  917. inline int COleDateTime::SetDate(int nYear, int nMonth, int nDay)
  918. {
  919. return SetDateTime(nYear, nMonth, nDay, 0, 0, 0);
  920. }
  921. inline int COleDateTime::SetTime(int nHour, int nMin, int nSec)
  922. {
  923. // Set date to zero date - 12/30/1899
  924. return SetDateTime(1899, 12, 30, nHour, nMin, nSec);
  925. }
  926. inline bool COleDateTime::ParseDateTime(LPCTSTR lpszDate, DWORD dwFlags, LCID lcid)
  927. {
  928. USES_CONVERSION;
  929. CString strDate = lpszDate;
  930. HRESULT hr;
  931. if (FAILED(hr = VarDateFromStr((LPOLESTR)T2COLE(strDate), lcid,
  932. dwFlags, &m_dt)))
  933. {
  934. if (hr == DISP_E_TYPEMISMATCH)
  935. {
  936. // Can't convert string to date, set 0 and invalidate
  937. m_dt = 0;
  938. m_status = invalid;
  939. return false;
  940. }
  941. else if (hr == DISP_E_OVERFLOW)
  942. {
  943. // Can't convert string to date, set -1 and invalidate
  944. m_dt = -1;
  945. m_status = invalid;
  946. return false;
  947. }
  948. else
  949. {
  950. ATLTRACE(atlTraceTime, 0, _T("\nCOleDateTime VarDateFromStr call failed.\n\t"));
  951. // Can't convert string to date, set -1 and invalidate
  952. m_dt = -1;
  953. m_status = invalid;
  954. return false;
  955. }
  956. }
  957. m_status = valid;
  958. return true;
  959. }
  960. #ifndef _ATL_MIN_CRT
  961. inline CString COleDateTime::Format(DWORD dwFlags, LCID lcid) const
  962. {
  963. // If null, return empty string
  964. if (GetStatus() == null)
  965. return _T("");
  966. // If invalid, return DateTime global string
  967. if (GetStatus() == invalid)
  968. {
  969. CString str;
  970. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  971. return str;
  972. return szInvalidDateTime;
  973. }
  974. CComBSTR bstr;
  975. if (FAILED(::VarBstrFromDate(m_dt, lcid, dwFlags, &bstr)))
  976. {
  977. CString str;
  978. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  979. return str;
  980. return szInvalidDateTime;
  981. }
  982. CString tmp = CString(bstr);
  983. return tmp;
  984. }
  985. inline CString COleDateTime::Format(LPCTSTR pFormat) const
  986. {
  987. // If null, return empty string
  988. if(GetStatus() == null)
  989. return _T("");
  990. // If invalid, return DateTime global string
  991. if(GetStatus() == invalid)
  992. {
  993. CString str;
  994. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  995. return str;
  996. return szInvalidDateTime;
  997. }
  998. UDATE ud;
  999. if (S_OK != VarUdateFromDate(m_dt, 0, &ud))
  1000. {
  1001. CString str;
  1002. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  1003. return str;
  1004. return szInvalidDateTime;
  1005. }
  1006. struct tm tmTemp;
  1007. tmTemp.tm_sec = ud.st.wSecond;
  1008. tmTemp.tm_min = ud.st.wMinute;
  1009. tmTemp.tm_hour = ud.st.wHour;
  1010. tmTemp.tm_mday = ud.st.wDay;
  1011. tmTemp.tm_mon = ud.st.wMonth - 1;
  1012. tmTemp.tm_year = ud.st.wYear - 1900;
  1013. tmTemp.tm_wday = ud.st.wDayOfWeek;
  1014. tmTemp.tm_yday = ud.wDayOfYear - 1;
  1015. tmTemp.tm_isdst = 0;
  1016. CString strDate;
  1017. LPTSTR lpszTemp = strDate.GetBufferSetLength(256);
  1018. _tcsftime(lpszTemp, strDate.GetLength(), pFormat, &tmTemp);
  1019. strDate.ReleaseBuffer();
  1020. return strDate;
  1021. }
  1022. inline CString COleDateTime::Format(UINT nFormatID) const
  1023. {
  1024. CString strFormat;
  1025. ATLVERIFY(strFormat.LoadString(nFormatID));
  1026. return Format(strFormat);
  1027. }
  1028. #endif // !_ATL_MIN_CRT
  1029. inline double COleDateTime::DoubleFromDate( DATE date )
  1030. {
  1031. double fTemp;
  1032. // No problem if positive
  1033. if( date >= 0 )
  1034. {
  1035. return( date );
  1036. }
  1037. // If negative, must convert since negative dates not continuous
  1038. // (examples: -1.25 to -.75, -1.50 to -.50, -1.75 to -.25)
  1039. fTemp = ceil( date );
  1040. return( fTemp-(date-fTemp) );
  1041. }
  1042. inline DATE COleDateTime::DateFromDouble( double f )
  1043. {
  1044. double fTemp;
  1045. // No problem if positive
  1046. if( f >= 0 )
  1047. {
  1048. return( f );
  1049. }
  1050. // If negative, must convert since negative dates not continuous
  1051. // (examples: -.75 to -1.25, -.50 to -1.50, -.25 to -1.75)
  1052. fTemp = floor( f ); // fTemp is now whole part
  1053. return( fTemp+(fTemp-f) );
  1054. }
  1055. /////////////////////////////////////////////////////////////////////////////
  1056. // CFileTimeSpan
  1057. /////////////////////////////////////////////////////////////////////////////
  1058. inline CFileTimeSpan::CFileTimeSpan() :
  1059. m_nSpan( 0 )
  1060. {
  1061. }
  1062. // REVIEW
  1063. inline CFileTimeSpan::CFileTimeSpan( const CFileTimeSpan& span ) :
  1064. m_nSpan( span.m_nSpan )
  1065. {
  1066. }
  1067. inline CFileTimeSpan::CFileTimeSpan( LONGLONG nSpan ) :
  1068. m_nSpan( nSpan )
  1069. {
  1070. }
  1071. inline CFileTimeSpan& CFileTimeSpan::operator=( const CFileTimeSpan& span )
  1072. {
  1073. m_nSpan = span.m_nSpan;
  1074. return( *this );
  1075. }
  1076. inline CFileTimeSpan& CFileTimeSpan::operator+=( CFileTimeSpan span )
  1077. {
  1078. m_nSpan += span.m_nSpan;
  1079. return( *this );
  1080. }
  1081. inline CFileTimeSpan& CFileTimeSpan::operator-=( CFileTimeSpan span )
  1082. {
  1083. m_nSpan -= span.m_nSpan;
  1084. return( *this );
  1085. }
  1086. inline CFileTimeSpan CFileTimeSpan::operator+( CFileTimeSpan span ) const
  1087. {
  1088. return( CFileTimeSpan( m_nSpan+span.m_nSpan ) );
  1089. }
  1090. inline CFileTimeSpan CFileTimeSpan::operator-( CFileTimeSpan span ) const
  1091. {
  1092. return( CFileTimeSpan( m_nSpan-span.m_nSpan ) );
  1093. }
  1094. inline bool CFileTimeSpan::operator==( CFileTimeSpan span ) const
  1095. {
  1096. return( m_nSpan == span.m_nSpan );
  1097. }
  1098. inline bool CFileTimeSpan::operator!=( CFileTimeSpan span ) const
  1099. {
  1100. return( m_nSpan != span.m_nSpan );
  1101. }
  1102. inline bool CFileTimeSpan::operator<( CFileTimeSpan span ) const
  1103. {
  1104. return( m_nSpan < span.m_nSpan );
  1105. }
  1106. inline bool CFileTimeSpan::operator>( CFileTimeSpan span ) const
  1107. {
  1108. return( m_nSpan > span.m_nSpan );
  1109. }
  1110. inline bool CFileTimeSpan::operator<=( CFileTimeSpan span ) const
  1111. {
  1112. return( m_nSpan <= span.m_nSpan );
  1113. }
  1114. inline bool CFileTimeSpan::operator>=( CFileTimeSpan span ) const
  1115. {
  1116. return( m_nSpan >= span.m_nSpan );
  1117. }
  1118. inline LONGLONG CFileTimeSpan::GetTimeSpan() const
  1119. {
  1120. return( m_nSpan );
  1121. }
  1122. inline void CFileTimeSpan::SetTimeSpan( LONGLONG nSpan )
  1123. {
  1124. m_nSpan = nSpan;
  1125. }
  1126. /////////////////////////////////////////////////////////////////////////////
  1127. // CFileTime
  1128. /////////////////////////////////////////////////////////////////////////////
  1129. inline CFileTime::CFileTime()
  1130. {
  1131. dwLowDateTime = 0;
  1132. dwHighDateTime = 0;
  1133. }
  1134. inline CFileTime::CFileTime( const FILETIME& ft )
  1135. {
  1136. dwLowDateTime = ft.dwLowDateTime;
  1137. dwHighDateTime = ft.dwHighDateTime;
  1138. }
  1139. inline CFileTime::CFileTime( ULONGLONG nTime )
  1140. {
  1141. dwLowDateTime = DWORD( nTime );
  1142. dwHighDateTime = DWORD( nTime>>32 );
  1143. }
  1144. inline CFileTime& CFileTime::operator=( const FILETIME& ft )
  1145. {
  1146. dwLowDateTime = ft.dwLowDateTime;
  1147. dwHighDateTime = ft.dwHighDateTime;
  1148. return( *this );
  1149. }
  1150. inline CFileTime CFileTime::GetCurrentTime()
  1151. {
  1152. CFileTime ft;
  1153. GetSystemTimeAsFileTime(&ft);
  1154. return ft;
  1155. }
  1156. inline CFileTime& CFileTime::operator+=( CFileTimeSpan span )
  1157. {
  1158. SetTime( GetTime()+span.GetTimeSpan() );
  1159. return( *this );
  1160. }
  1161. inline CFileTime& CFileTime::operator-=( CFileTimeSpan span )
  1162. {
  1163. SetTime( GetTime()-span.GetTimeSpan() );
  1164. return( *this );
  1165. }
  1166. inline CFileTime CFileTime::operator+( CFileTimeSpan span ) const
  1167. {
  1168. return( CFileTime( GetTime()+span.GetTimeSpan() ) );
  1169. }
  1170. inline CFileTime CFileTime::operator-( CFileTimeSpan span ) const
  1171. {
  1172. return( CFileTime( GetTime()-span.GetTimeSpan() ) );
  1173. }
  1174. inline CFileTimeSpan CFileTime::operator-( CFileTime ft ) const
  1175. {
  1176. return( CFileTimeSpan( GetTime()-ft.GetTime() ) );
  1177. }
  1178. inline bool CFileTime::operator==( CFileTime ft ) const
  1179. {
  1180. return( GetTime() == ft.GetTime() );
  1181. }
  1182. inline bool CFileTime::operator!=( CFileTime ft ) const
  1183. {
  1184. return( GetTime() != ft.GetTime() );
  1185. }
  1186. inline bool CFileTime::operator<( CFileTime ft ) const
  1187. {
  1188. return( GetTime() < ft.GetTime() );
  1189. }
  1190. inline bool CFileTime::operator>( CFileTime ft ) const
  1191. {
  1192. return( GetTime() > ft.GetTime() );
  1193. }
  1194. inline bool CFileTime::operator<=( CFileTime ft ) const
  1195. {
  1196. return( GetTime() <= ft.GetTime() );
  1197. }
  1198. inline bool CFileTime::operator>=( CFileTime ft ) const
  1199. {
  1200. return( GetTime() >= ft.GetTime() );
  1201. }
  1202. inline ULONGLONG CFileTime::GetTime() const
  1203. {
  1204. return( (ULONGLONG( dwHighDateTime )<<32)|dwLowDateTime );
  1205. }
  1206. inline void CFileTime::SetTime( ULONGLONG nTime )
  1207. {
  1208. dwLowDateTime = DWORD( nTime );
  1209. dwHighDateTime = DWORD( nTime>>32 );
  1210. }
  1211. inline CFileTime CFileTime::UTCToLocal() const
  1212. {
  1213. CFileTime ftLocal;
  1214. ::FileTimeToLocalFileTime( this, &ftLocal );
  1215. return( ftLocal );
  1216. }
  1217. inline CFileTime CFileTime::LocalToUTC() const
  1218. {
  1219. CFileTime ftUTC;
  1220. ::LocalFileTimeToFileTime( this, &ftUTC );
  1221. return( ftUTC );
  1222. }
  1223. } // namespace ATL
  1224. #endif //__ATLTIME_INL__