ATLComTime.h 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. // This is a part of the Active Template Library.
  2. // Copyright (C) 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 __ATLCOMTIME_H__
  11. #define __ATLCOMTIME_H__
  12. #pragma once
  13. #pragma warning(push)
  14. #pragma warning( disable : 4159 ) //pragma has popped previously pushed identifier
  15. #pragma warning( disable : 4127 ) //constant expression
  16. #include <atldef.h>
  17. #include <time.h>
  18. #ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  19. //#include <atltime.h>
  20. #endif
  21. #include <atlstr.h>
  22. #include <math.h>
  23. #include <oleauto.h>
  24. #ifndef __oledb_h__
  25. #include <oledb.h>
  26. #endif // __oledb_h__
  27. #if defined(_M_IX86)
  28. #pragma pack(push, 4)
  29. #else
  30. #pragma pack(push, ATL_PACKING)
  31. #endif
  32. struct tagVARIANT;
  33. typedef tagVARIANT VARIANT;
  34. typedef double DATE;
  35. namespace ATL
  36. {
  37. class COleDateTimeSpan
  38. {
  39. private:
  40. static const long maxDaysInSpan = 3615897L;
  41. // Constructors
  42. public:
  43. COleDateTimeSpan() throw();
  44. COleDateTimeSpan(_In_ double dblSpanSrc) throw();
  45. COleDateTimeSpan(
  46. _In_ LONG lDays,
  47. _In_ int nHours,
  48. _In_ int nMins,
  49. _In_ int nSecs) throw();
  50. // Attributes
  51. enum DateTimeSpanStatus
  52. {
  53. valid = 0,
  54. invalid = 1, // Invalid span (out of range, etc.)
  55. null = 2, // Literally has no value
  56. };
  57. double m_span;
  58. DateTimeSpanStatus m_status;
  59. void SetStatus(_In_ DateTimeSpanStatus status) throw();
  60. DateTimeSpanStatus GetStatus() const throw();
  61. double GetTotalDays() const throw(); // span in days (about -3.65e6 to 3.65e6)
  62. double GetTotalHours() const throw(); // span in hours (about -8.77e7 to 8.77e6)
  63. double GetTotalMinutes() const throw(); // span in minutes (about -5.26e9 to 5.26e9)
  64. double GetTotalSeconds() const throw(); // span in seconds (about -3.16e11 to 3.16e11)
  65. LONG GetDays() const throw(); // component days in span
  66. LONG GetHours() const throw(); // component hours in span (-23 to 23)
  67. LONG GetMinutes() const throw(); // component minutes in span (-59 to 59)
  68. LONG GetSeconds() const throw(); // component seconds in span (-59 to 59)
  69. // Operations
  70. COleDateTimeSpan& operator=(_In_ double dblSpanSrc) throw();
  71. bool operator==(_In_ const COleDateTimeSpan& dateSpan) const throw();
  72. bool operator!=(_In_ const COleDateTimeSpan& dateSpan) const throw();
  73. bool operator<(_In_ const COleDateTimeSpan& dateSpan) const throw();
  74. bool operator>(_In_ const COleDateTimeSpan& dateSpan) const throw();
  75. bool operator<=(_In_ const COleDateTimeSpan& dateSpan) const throw();
  76. bool operator>=(_In_ const COleDateTimeSpan& dateSpan) const throw();
  77. // DateTimeSpan math
  78. COleDateTimeSpan operator+(_In_ const COleDateTimeSpan& dateSpan) const throw();
  79. COleDateTimeSpan operator-(_In_ const COleDateTimeSpan& dateSpan) const throw();
  80. COleDateTimeSpan& operator+=(_In_ const COleDateTimeSpan dateSpan) throw();
  81. COleDateTimeSpan& operator-=(_In_ const COleDateTimeSpan dateSpan) throw();
  82. COleDateTimeSpan operator-() const throw();
  83. operator double() const throw();
  84. void SetDateTimeSpan(
  85. _In_ LONG lDays,
  86. _In_ int nHours,
  87. _In_ int nMins,
  88. _In_ int nSecs) throw();
  89. // formatting
  90. CString Format(_In_z_ LPCTSTR pFormat) const;
  91. CString Format(_In_ UINT nID) const;
  92. // Implementation
  93. void CheckRange();
  94. static const double OLE_DATETIME_HALFSECOND;
  95. };
  96. class COleDateTime
  97. {
  98. // Constructors
  99. public:
  100. static COleDateTime WINAPI GetCurrentTime() throw();
  101. COleDateTime() throw();
  102. COleDateTime(_In_ const VARIANT& varSrc) throw();
  103. COleDateTime(_In_ DATE dtSrc) throw();
  104. COleDateTime(_In_ __time32_t timeSrc) throw();
  105. COleDateTime(_In_ __time64_t timeSrc) throw();
  106. COleDateTime(_In_ const SYSTEMTIME& systimeSrc) throw();
  107. COleDateTime(_In_ const FILETIME& filetimeSrc) throw();
  108. COleDateTime(
  109. _In_ int nYear,
  110. _In_ int nMonth,
  111. _In_ int nDay,
  112. _In_ int nHour,
  113. _In_ int nMin,
  114. _In_ int nSec) throw();
  115. COleDateTime(_In_ WORD wDosDate, _In_ WORD wDosTime) throw();
  116. #ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  117. COleDateTime(_In_ const DBTIMESTAMP& dbts) throw();
  118. _Success_(return != false) bool GetAsDBTIMESTAMP(_Out_ DBTIMESTAMP& dbts) const throw();
  119. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  120. // Attributes
  121. enum DateTimeStatus
  122. {
  123. error = -1,
  124. valid = 0,
  125. invalid = 1, // Invalid date (out of range, etc.)
  126. null = 2, // Literally has no value
  127. };
  128. DATE m_dt;
  129. DateTimeStatus m_status;
  130. void SetStatus(_In_ DateTimeStatus status) throw();
  131. DateTimeStatus GetStatus() const throw();
  132. _Success_(return != false) bool GetAsSystemTime(_Out_ SYSTEMTIME& sysTime) const throw();
  133. _Success_(return != false) bool GetAsUDATE(_Out_ UDATE& udate) const throw();
  134. int GetYear() const throw();
  135. // Month of year (1 = January)
  136. int GetMonth() const throw();
  137. // Day of month (1-31)
  138. int GetDay() const throw();
  139. // Hour in day (0-23)
  140. int GetHour() const throw();
  141. // Minute in hour (0-59)
  142. int GetMinute() const throw();
  143. // Second in minute (0-59)
  144. int GetSecond() const throw();
  145. // Day of week (1 = Sunday, 2 = Monday, ..., 7 = Saturday)
  146. int GetDayOfWeek() const throw();
  147. // Days since start of year (1 = January 1)
  148. int GetDayOfYear() const throw();
  149. // Operations
  150. COleDateTime& operator=(_In_ const VARIANT& varSrc) throw();
  151. COleDateTime& operator=(_In_ DATE dtSrc) throw();
  152. COleDateTime& operator=(_In_ const __time32_t& timeSrc) throw();
  153. COleDateTime& operator=(_In_ const __time64_t& timeSrc) throw();
  154. COleDateTime& operator=(_In_ const SYSTEMTIME& systimeSrc) throw();
  155. #ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  156. COleDateTime& operator=(_In_ const FILETIME& filetimeSrc) throw();
  157. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  158. COleDateTime& operator=(_In_ const UDATE& udate) throw();
  159. bool operator==(_In_ const COleDateTime& date) const throw();
  160. bool operator!=(_In_ const COleDateTime& date) const throw();
  161. bool operator<(_In_ const COleDateTime& date) const throw();
  162. bool operator>(_In_ const COleDateTime& date) const throw();
  163. bool operator<=(_In_ const COleDateTime& date) const throw();
  164. bool operator>=(_In_ const COleDateTime& date) const throw();
  165. // DateTime math
  166. COleDateTime operator+(_In_ COleDateTimeSpan dateSpan) const throw();
  167. COleDateTime operator-(_In_ COleDateTimeSpan dateSpan) const throw();
  168. COleDateTime& operator+=(_In_ COleDateTimeSpan dateSpan) throw();
  169. COleDateTime& operator-=(_In_ COleDateTimeSpan dateSpan) throw();
  170. // DateTimeSpan math
  171. COleDateTimeSpan operator-(_In_ const COleDateTime& date) const throw();
  172. operator DATE() const throw();
  173. int SetDateTime(
  174. _In_ int nYear,
  175. _In_ int nMonth,
  176. _In_ int nDay,
  177. _In_ int nHour,
  178. _In_ int nMin,
  179. _In_ int nSec) throw();
  180. int SetDate(_In_ int nYear, _In_ int nMonth, _In_ int nDay) throw();
  181. int SetTime(_In_ int nHour, _In_ int nMin, _In_ int nSec) throw();
  182. bool ParseDateTime(
  183. _In_opt_z_ LPCTSTR lpszDate,
  184. _In_ DWORD dwFlags = 0,
  185. _In_ LCID lcid = LANG_USER_DEFAULT) throw();
  186. #ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  187. // formatting
  188. CString Format(_In_ DWORD dwFlags = 0, _In_ LCID lcid = LANG_USER_DEFAULT) const;
  189. CString Format(_In_z_ LPCTSTR lpszFormat) const;
  190. CString Format(_In_ UINT nFormatID) const;
  191. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  192. protected:
  193. static double WINAPI DoubleFromDate(_In_ DATE date) throw();
  194. static DATE WINAPI DateFromDouble(_In_ double f) throw();
  195. void CheckRange();
  196. BOOL ConvertSystemTimeToVariantTime(_In_ const SYSTEMTIME& systimeSrc);
  197. };
  198. #ifndef _ATL_STATIC_LIB_IMPL
  199. /////////////////////////////////////////////////////////////////////////////
  200. // COleDateTimeSpan
  201. /////////////////////////////////////////////////////////////////////////////
  202. inline COleDateTimeSpan::COleDateTimeSpan() throw() : m_span(0), m_status(valid)
  203. {
  204. }
  205. inline COleDateTimeSpan::COleDateTimeSpan(_In_ double dblSpanSrc) throw() :
  206. m_span(dblSpanSrc), m_status(valid)
  207. {
  208. CheckRange();
  209. }
  210. inline COleDateTimeSpan::COleDateTimeSpan(
  211. _In_ LONG lDays,
  212. _In_ int nHours,
  213. _In_ int nMins,
  214. _In_ int nSecs) throw()
  215. {
  216. SetDateTimeSpan(lDays, nHours, nMins, nSecs);
  217. }
  218. inline void COleDateTimeSpan::SetStatus(_In_ DateTimeSpanStatus status) throw()
  219. {
  220. m_status = status;
  221. }
  222. inline COleDateTimeSpan::DateTimeSpanStatus COleDateTimeSpan::GetStatus() const throw()
  223. {
  224. return m_status;
  225. }
  226. __declspec(selectany) const double
  227. COleDateTimeSpan::OLE_DATETIME_HALFSECOND =
  228. 1.0 / (2.0 * (60.0 * 60.0 * 24.0));
  229. inline double COleDateTimeSpan::GetTotalDays() const throw()
  230. {
  231. ATLASSERT(GetStatus() == valid);
  232. return (double)LONGLONG(m_span + (m_span < 0 ?
  233. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND));
  234. }
  235. inline double COleDateTimeSpan::GetTotalHours() const throw()
  236. {
  237. ATLASSERT(GetStatus() == valid);
  238. return (double)LONGLONG((m_span + (m_span < 0 ?
  239. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND)) * 24);
  240. }
  241. inline double COleDateTimeSpan::GetTotalMinutes() const throw()
  242. {
  243. ATLASSERT(GetStatus() == valid);
  244. return (double)LONGLONG((m_span + (m_span < 0 ?
  245. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND)) * (24 * 60));
  246. }
  247. inline double COleDateTimeSpan::GetTotalSeconds() const throw()
  248. {
  249. ATLASSERT(GetStatus() == valid);
  250. return (double)LONGLONG((m_span + (m_span < 0 ?
  251. -OLE_DATETIME_HALFSECOND : OLE_DATETIME_HALFSECOND)) * (24 * 60 * 60));
  252. }
  253. inline LONG COleDateTimeSpan::GetDays() const throw()
  254. {
  255. ATLASSERT(GetStatus() == valid);
  256. return LONG(GetTotalDays());
  257. }
  258. inline LONG COleDateTimeSpan::GetHours() const throw()
  259. {
  260. double dPartialDayHours = GetTotalHours() - (GetTotalDays() * 24);
  261. return LONG(dPartialDayHours) % 24;
  262. }
  263. inline LONG COleDateTimeSpan::GetMinutes() const throw()
  264. {
  265. double dPartialHourMinutes = GetTotalMinutes() - (GetTotalHours() * 60);
  266. return LONG(dPartialHourMinutes) % 60;
  267. }
  268. inline LONG COleDateTimeSpan::GetSeconds() const throw()
  269. {
  270. double dPartialMinuteSeconds = GetTotalSeconds() - (GetTotalMinutes() * 60);
  271. return LONG(dPartialMinuteSeconds) % 60;
  272. }
  273. inline COleDateTimeSpan& COleDateTimeSpan::operator=(_In_ double dblSpanSrc) throw()
  274. {
  275. m_span = dblSpanSrc;
  276. m_status = valid;
  277. CheckRange();
  278. return *this;
  279. }
  280. inline bool COleDateTimeSpan::operator==(
  281. _In_ const COleDateTimeSpan& dateSpan) const throw()
  282. {
  283. if(GetStatus() == dateSpan.GetStatus())
  284. {
  285. if(GetStatus() == valid)
  286. {
  287. // it has to be in precision range to say that it as equal
  288. if (m_span + OLE_DATETIME_HALFSECOND > dateSpan.m_span &&
  289. m_span - OLE_DATETIME_HALFSECOND < dateSpan.m_span)
  290. {
  291. return true;
  292. }
  293. else
  294. {
  295. return false;
  296. }
  297. }
  298. return (GetStatus() == null);
  299. }
  300. return false;
  301. }
  302. inline bool COleDateTimeSpan::operator!=(
  303. _In_ const COleDateTimeSpan& dateSpan) const throw()
  304. {
  305. return !operator==(dateSpan);
  306. }
  307. inline bool COleDateTimeSpan::operator<(
  308. _In_ const COleDateTimeSpan& dateSpan) const throw()
  309. {
  310. ATLASSERT(GetStatus() == valid);
  311. ATLASSERT(dateSpan.GetStatus() == valid);
  312. if( (GetStatus() == valid) && (GetStatus() == dateSpan.GetStatus()) )
  313. return m_span < dateSpan.m_span;
  314. return false;
  315. }
  316. inline bool COleDateTimeSpan::operator>(
  317. _In_ const COleDateTimeSpan& dateSpan) const throw()
  318. {
  319. ATLASSERT(GetStatus() == valid);
  320. ATLASSERT(dateSpan.GetStatus() == valid);
  321. if( (GetStatus() == valid) && (GetStatus() == dateSpan.GetStatus()) )
  322. return m_span > dateSpan.m_span ;
  323. return false;
  324. }
  325. inline bool COleDateTimeSpan::operator<=(
  326. _In_ const COleDateTimeSpan& dateSpan) const throw()
  327. {
  328. return operator<(dateSpan) || operator==(dateSpan);
  329. }
  330. inline bool COleDateTimeSpan::operator>=(
  331. _In_ const COleDateTimeSpan& dateSpan) const throw()
  332. {
  333. return operator>(dateSpan) || operator==(dateSpan);
  334. }
  335. inline COleDateTimeSpan COleDateTimeSpan::operator+(
  336. _In_ const COleDateTimeSpan& dateSpan) const throw()
  337. {
  338. COleDateTimeSpan dateSpanTemp;
  339. // If either operand Null, result Null
  340. if (GetStatus() == null || dateSpan.GetStatus() == null)
  341. {
  342. dateSpanTemp.SetStatus(null);
  343. return dateSpanTemp;
  344. }
  345. // If either operand Invalid, result Invalid
  346. if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
  347. {
  348. dateSpanTemp.SetStatus(invalid);
  349. return dateSpanTemp;
  350. }
  351. // Add spans and validate within legal range
  352. dateSpanTemp.m_span = m_span + dateSpan.m_span;
  353. dateSpanTemp.CheckRange();
  354. return dateSpanTemp;
  355. }
  356. inline COleDateTimeSpan COleDateTimeSpan::operator-(
  357. _In_ const COleDateTimeSpan& dateSpan) const throw()
  358. {
  359. COleDateTimeSpan dateSpanTemp;
  360. // If either operand Null, result Null
  361. if (GetStatus() == null || dateSpan.GetStatus() == null)
  362. {
  363. dateSpanTemp.SetStatus(null);
  364. return dateSpanTemp;
  365. }
  366. // If either operand Invalid, result Invalid
  367. if (GetStatus() == invalid || dateSpan.GetStatus() == invalid)
  368. {
  369. dateSpanTemp.SetStatus(invalid);
  370. return dateSpanTemp;
  371. }
  372. // Subtract spans and validate within legal range
  373. dateSpanTemp.m_span = m_span - dateSpan.m_span;
  374. dateSpanTemp.CheckRange();
  375. return dateSpanTemp;
  376. }
  377. inline COleDateTimeSpan& COleDateTimeSpan::operator+=(
  378. _In_ const COleDateTimeSpan dateSpan) throw()
  379. {
  380. ATLASSERT(GetStatus() == valid);
  381. ATLASSERT(dateSpan.GetStatus() == valid);
  382. *this = *this + dateSpan;
  383. CheckRange();
  384. return *this;
  385. }
  386. inline COleDateTimeSpan& COleDateTimeSpan::operator-=(
  387. _In_ const COleDateTimeSpan dateSpan) throw()
  388. {
  389. ATLASSERT(GetStatus() == valid);
  390. ATLASSERT(dateSpan.GetStatus() == valid);
  391. *this = *this - dateSpan;
  392. CheckRange();
  393. return *this;
  394. }
  395. inline COleDateTimeSpan COleDateTimeSpan::operator-() const throw()
  396. {
  397. return -this->m_span;
  398. }
  399. inline COleDateTimeSpan::operator double() const throw()
  400. {
  401. return m_span;
  402. }
  403. inline void COleDateTimeSpan::SetDateTimeSpan(
  404. _In_ LONG lDays,
  405. _In_ int nHours,
  406. _In_ int nMins,
  407. _In_ int nSecs) throw()
  408. {
  409. // Set date span by breaking into fractional days (all input ranges valid)
  410. m_span = lDays + ((double)nHours)/24 + ((double)nMins)/(24*60) +
  411. ((double)nSecs)/(24*60*60);
  412. m_status = valid;
  413. CheckRange();
  414. }
  415. inline void COleDateTimeSpan::CheckRange()
  416. {
  417. if(m_span < -maxDaysInSpan || m_span > maxDaysInSpan)
  418. {
  419. m_status = invalid;
  420. }
  421. }
  422. /////////////////////////////////////////////////////////////////////////////
  423. // COleDateTime
  424. /////////////////////////////////////////////////////////////////////////////
  425. inline COleDateTime WINAPI COleDateTime::GetCurrentTime() throw()
  426. {
  427. return COleDateTime(::_time64(NULL));
  428. }
  429. inline COleDateTime::COleDateTime() throw() :
  430. m_dt( 0 ), m_status(valid)
  431. {
  432. }
  433. inline COleDateTime::COleDateTime(_In_ const VARIANT& varSrc) throw() :
  434. m_dt( 0 ), m_status(valid)
  435. {
  436. *this = varSrc;
  437. }
  438. inline COleDateTime::COleDateTime(_In_ DATE dtSrc) throw() :
  439. m_dt( dtSrc ), m_status(valid)
  440. {
  441. }
  442. inline COleDateTime::COleDateTime(_In_ __time32_t timeSrc) throw() :
  443. m_dt( 0 ), m_status(valid)
  444. {
  445. *this = timeSrc;
  446. }
  447. inline COleDateTime::COleDateTime(_In_ __time64_t timeSrc) throw() :
  448. m_dt( 0 ), m_status(valid)
  449. {
  450. *this = timeSrc;
  451. }
  452. inline COleDateTime::COleDateTime(_In_ const SYSTEMTIME& systimeSrc) throw() :
  453. m_dt( 0 ), m_status(valid)
  454. {
  455. *this = systimeSrc;
  456. }
  457. inline COleDateTime::COleDateTime(_In_ const FILETIME& filetimeSrc) throw() :
  458. m_dt( 0 ), m_status(valid)
  459. {
  460. *this = filetimeSrc;
  461. }
  462. inline COleDateTime::COleDateTime(
  463. _In_ int nYear,
  464. _In_ int nMonth,
  465. _In_ int nDay,
  466. _In_ int nHour,
  467. _In_ int nMin,
  468. _In_ int nSec) throw()
  469. {
  470. SetDateTime(nYear, nMonth, nDay, nHour, nMin, nSec);
  471. }
  472. #ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  473. inline COleDateTime::COleDateTime(
  474. _In_ WORD wDosDate,
  475. _In_ WORD wDosTime) throw()
  476. {
  477. m_status = ::DosDateTimeToVariantTime(wDosDate, wDosTime, &m_dt) ?
  478. valid : invalid;
  479. }
  480. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  481. inline void COleDateTime::SetStatus(_In_ DateTimeStatus status) throw()
  482. {
  483. m_status = status;
  484. }
  485. inline COleDateTime::DateTimeStatus COleDateTime::GetStatus() const throw()
  486. {
  487. return m_status;
  488. }
  489. inline _Success_(return != false) bool COleDateTime::GetAsSystemTime(_Out_ SYSTEMTIME& sysTime) const throw()
  490. {
  491. return GetStatus() == valid && ::VariantTimeToSystemTime(m_dt, &sysTime) == TRUE;
  492. }
  493. _Success_(return != false)
  494. inline bool COleDateTime::GetAsUDATE(_Out_ UDATE &udate) const throw()
  495. {
  496. return SUCCEEDED(::VarUdateFromDate(m_dt, 0, &udate));
  497. }
  498. inline int COleDateTime::GetYear() const throw()
  499. {
  500. SYSTEMTIME st = {0};
  501. return GetAsSystemTime(st) ? st.wYear : error;
  502. }
  503. inline int COleDateTime::GetMonth() const throw()
  504. {
  505. SYSTEMTIME st = {0};
  506. return GetAsSystemTime(st) ? st.wMonth : error;
  507. }
  508. inline int COleDateTime::GetDay() const throw()
  509. {
  510. SYSTEMTIME st = {0};
  511. return GetAsSystemTime(st) ? st.wDay : error;
  512. }
  513. inline int COleDateTime::GetHour() const throw()
  514. {
  515. SYSTEMTIME st = {0};
  516. return GetAsSystemTime(st) ? st.wHour : error;
  517. }
  518. inline int COleDateTime::GetMinute() const throw()
  519. {
  520. SYSTEMTIME st = {0};
  521. return GetAsSystemTime(st) ? st.wMinute : error;
  522. }
  523. inline int COleDateTime::GetSecond() const throw()
  524. {
  525. SYSTEMTIME st = {0};
  526. return GetAsSystemTime(st) ? st.wSecond : error;
  527. }
  528. inline int COleDateTime::GetDayOfWeek() const throw()
  529. {
  530. SYSTEMTIME st = {0};
  531. return GetAsSystemTime(st) ? st.wDayOfWeek + 1 : error;
  532. }
  533. inline int COleDateTime::GetDayOfYear() const throw()
  534. {
  535. UDATE udate = {0};
  536. return GetAsUDATE(udate) ? udate.wDayOfYear : error;
  537. }
  538. inline COleDateTime& COleDateTime::operator=(_In_ const VARIANT& varSrc) throw()
  539. {
  540. if (varSrc.vt != VT_DATE)
  541. {
  542. VARIANT varDest;
  543. varDest.vt = VT_EMPTY;
  544. if(SUCCEEDED(::VariantChangeType(&varDest, const_cast<VARIANT *>(&varSrc), 0, VT_DATE)))
  545. {
  546. m_dt = varDest.date;
  547. m_status = valid;
  548. }
  549. else
  550. m_status = invalid;
  551. }
  552. else
  553. {
  554. m_dt = varSrc.date;
  555. m_status = valid;
  556. }
  557. return *this;
  558. }
  559. inline COleDateTime& COleDateTime::operator=(_In_ DATE dtSrc) throw()
  560. {
  561. m_dt = dtSrc;
  562. m_status = valid;
  563. return *this;
  564. }
  565. inline COleDateTime& COleDateTime::operator=(_In_ const __time32_t& timeSrc) throw()
  566. {
  567. return operator=(static_cast<__time64_t>(timeSrc));
  568. }
  569. #ifndef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  570. inline bool GetAsSystemTimeHelper(_In_ const __time64_t& timeSrc, _Out_ SYSTEMTIME& timeDest)
  571. {
  572. struct tm ttm;
  573. if (_localtime64_s(&ttm, &timeSrc) != 0)
  574. {
  575. return false;
  576. }
  577. timeDest.wYear = (WORD) (1900 + ttm.tm_year);
  578. timeDest.wMonth = (WORD) (1 + ttm.tm_mon);
  579. timeDest.wDayOfWeek = (WORD) ttm.tm_wday;
  580. timeDest.wDay = (WORD) ttm.tm_mday;
  581. timeDest.wHour = (WORD) ttm.tm_hour;
  582. timeDest.wMinute = (WORD) ttm.tm_min;
  583. timeDest.wSecond = (WORD) ttm.tm_sec;
  584. timeDest.wMilliseconds = 0;
  585. return true;
  586. }
  587. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  588. inline COleDateTime& COleDateTime::operator=(_In_ const __time64_t& timeSrc) throw()
  589. {
  590. #ifndef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  591. SYSTEMTIME st;
  592. m_status = GetAsSystemTimeHelper(timeSrc, st) &&
  593. ConvertSystemTimeToVariantTime(st) ? valid : invalid;
  594. #else
  595. SYSTEMTIME st;
  596. CTime tmp(timeSrc);
  597. m_status = tmp.GetAsSystemTime(st) &&
  598. ConvertSystemTimeToVariantTime(st) ? valid : invalid;
  599. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  600. return *this;
  601. }
  602. inline COleDateTime &COleDateTime::operator=(_In_ const SYSTEMTIME &systimeSrc) throw()
  603. {
  604. m_status = ConvertSystemTimeToVariantTime(systimeSrc) ? valid : invalid;
  605. return *this;
  606. }
  607. #ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  608. inline COleDateTime &COleDateTime::operator=(_In_ const FILETIME &filetimeSrc) throw()
  609. {
  610. FILETIME ftl;
  611. SYSTEMTIME st;
  612. m_status = ::FileTimeToLocalFileTime(&filetimeSrc, &ftl) &&
  613. ::FileTimeToSystemTime(&ftl, &st) &&
  614. ConvertSystemTimeToVariantTime(st) ? valid : invalid;
  615. return *this;
  616. }
  617. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  618. inline BOOL COleDateTime::ConvertSystemTimeToVariantTime(_In_ const SYSTEMTIME& systimeSrc)
  619. {
  620. return AtlConvertSystemTimeToVariantTime(systimeSrc,&m_dt);
  621. }
  622. inline COleDateTime &COleDateTime::operator=(_In_ const UDATE &udate) throw()
  623. {
  624. m_status = (S_OK == VarDateFromUdate((UDATE*)&udate, 0, &m_dt)) ? valid : invalid;
  625. return *this;
  626. }
  627. inline bool COleDateTime::operator==(_In_ const COleDateTime& date) const throw()
  628. {
  629. if(GetStatus() == date.GetStatus())
  630. {
  631. if(GetStatus() == valid)
  632. {
  633. // it has to be in precision range to say that it as equal
  634. if (m_dt + COleDateTimeSpan::OLE_DATETIME_HALFSECOND > date.m_dt &&
  635. m_dt - COleDateTimeSpan::OLE_DATETIME_HALFSECOND < date.m_dt)
  636. {
  637. return true;
  638. }
  639. else
  640. {
  641. return false;
  642. }
  643. }
  644. return (GetStatus() == null);
  645. }
  646. return false;
  647. }
  648. inline bool COleDateTime::operator!=(_In_ const COleDateTime& date) const throw()
  649. {
  650. return !operator==(date);
  651. }
  652. inline bool COleDateTime::operator<(_In_ const COleDateTime& date) const throw()
  653. {
  654. ATLASSERT(GetStatus() == valid);
  655. ATLASSERT(date.GetStatus() == valid);
  656. if( (GetStatus() == valid) && (GetStatus() == date.GetStatus()) )
  657. return( DoubleFromDate( m_dt ) < DoubleFromDate( date.m_dt ) );
  658. return false;
  659. }
  660. inline bool COleDateTime::operator>(_In_ const COleDateTime& date) const throw()
  661. {
  662. ATLASSERT(GetStatus() == valid);
  663. ATLASSERT(date.GetStatus() == valid);
  664. if( (GetStatus() == valid) && (GetStatus() == date.GetStatus()) )
  665. return( DoubleFromDate( m_dt ) > DoubleFromDate( date.m_dt ) );
  666. return false;
  667. }
  668. inline bool COleDateTime::operator<=(_In_ const COleDateTime& date) const throw()
  669. {
  670. return operator<(date) || operator==(date);
  671. }
  672. inline bool COleDateTime::operator>=(_In_ const COleDateTime& date) const throw()
  673. {
  674. return operator>(date) || operator==(date);
  675. }
  676. inline COleDateTime COleDateTime::operator+(_In_ COleDateTimeSpan dateSpan) const throw()
  677. {
  678. ATLASSERT(GetStatus() == valid);
  679. ATLASSERT(dateSpan.GetStatus() == valid);
  680. return( COleDateTime( DateFromDouble( DoubleFromDate( m_dt )+(double)dateSpan ) ) );
  681. }
  682. inline COleDateTime COleDateTime::operator-(_In_ COleDateTimeSpan dateSpan) const throw()
  683. {
  684. ATLASSERT(GetStatus() == valid);
  685. ATLASSERT(dateSpan.GetStatus() == valid);
  686. return( COleDateTime( DateFromDouble( DoubleFromDate( m_dt )-(double)dateSpan ) ) );
  687. }
  688. inline COleDateTime& COleDateTime::operator+=(_In_ COleDateTimeSpan dateSpan) throw()
  689. {
  690. ATLASSERT(GetStatus() == valid);
  691. ATLASSERT(dateSpan.GetStatus() == valid);
  692. m_dt = DateFromDouble( DoubleFromDate( m_dt )+(double)dateSpan );
  693. return( *this );
  694. }
  695. inline COleDateTime& COleDateTime::operator-=(_In_ COleDateTimeSpan dateSpan) throw()
  696. {
  697. ATLASSERT(GetStatus() == valid);
  698. ATLASSERT(dateSpan.GetStatus() == valid);
  699. m_dt = DateFromDouble( DoubleFromDate( m_dt )-(double)dateSpan );
  700. return( *this );
  701. }
  702. inline COleDateTimeSpan COleDateTime::operator-(_In_ const COleDateTime& date) const throw()
  703. {
  704. ATLASSERT(GetStatus() == valid);
  705. ATLASSERT(date.GetStatus() == valid);
  706. return DoubleFromDate(m_dt) - DoubleFromDate(date.m_dt);
  707. }
  708. inline COleDateTime::operator DATE() const throw()
  709. {
  710. ATLASSERT(GetStatus() == valid);
  711. return( m_dt );
  712. }
  713. inline int COleDateTime::SetDateTime(
  714. _In_ int nYear,
  715. _In_ int nMonth,
  716. _In_ int nDay,
  717. _In_ int nHour,
  718. _In_ int nMin,
  719. _In_ int nSec) throw()
  720. {
  721. SYSTEMTIME st;
  722. ::ZeroMemory(&st, sizeof(SYSTEMTIME));
  723. st.wYear = WORD(nYear);
  724. st.wMonth = WORD(nMonth);
  725. st.wDay = WORD(nDay);
  726. st.wHour = WORD(nHour);
  727. st.wMinute = WORD(nMin);
  728. st.wSecond = WORD(nSec);
  729. m_status = ConvertSystemTimeToVariantTime(st) ? valid : invalid;
  730. return m_status;
  731. }
  732. inline int COleDateTime::SetDate(_In_ int nYear, _In_ int nMonth, _In_ int nDay) throw()
  733. {
  734. return SetDateTime(nYear, nMonth, nDay, 0, 0, 0);
  735. }
  736. inline int COleDateTime::SetTime(_In_ int nHour, _In_ int nMin, _In_ int nSec) throw()
  737. {
  738. // Set date to zero date - 12/30/1899
  739. return SetDateTime(1899, 12, 30, nHour, nMin, nSec);
  740. }
  741. inline double WINAPI COleDateTime::DoubleFromDate(_In_ DATE date) throw()
  742. {
  743. // We treat it as positive from -OLE_DATETIME_HALFSECOND because of numeric errors
  744. // If value is positive it doesn't need conversion
  745. if(date > -COleDateTimeSpan::OLE_DATETIME_HALFSECOND)
  746. {
  747. return date;
  748. }
  749. // If negative, must convert since negative dates not continuous
  750. // (examples: -1.25 to -.75, -1.50 to -.50, -1.75 to -.25)
  751. double fTemp = ceil(date);
  752. return fTemp - (date - fTemp);
  753. }
  754. inline DATE WINAPI COleDateTime::DateFromDouble(_In_ double f) throw()
  755. {
  756. // We treat it as positive from -OLE_DATETIME_HALFSECOND because of numeric errors
  757. // If value is positive it doesn't need conversion
  758. if(f > -COleDateTimeSpan::OLE_DATETIME_HALFSECOND )
  759. {
  760. return f;
  761. }
  762. // If negative, must convert since negative dates not continuous
  763. // (examples: -.75 to -1.25, -.50 to -1.50, -.25 to -1.75)
  764. double fTemp = floor(f); // fTemp is now whole part
  765. return fTemp + (fTemp - f);
  766. }
  767. inline void COleDateTime::CheckRange()
  768. {
  769. // About year 100 to about 9999
  770. if(m_dt > VTDATEGRE_MAX || m_dt < VTDATEGRE_MIN)
  771. {
  772. SetStatus(invalid);
  773. }
  774. }
  775. #endif // _ATL_STATIC_LIB_IMPL
  776. inline bool COleDateTime::ParseDateTime(
  777. _In_opt_z_ LPCTSTR lpszDate,
  778. _In_ DWORD dwFlags,
  779. _In_ LCID lcid) throw()
  780. {
  781. USES_CONVERSION_EX;
  782. LPCTSTR pszDate = ( lpszDate == NULL ) ? _T("") : lpszDate;
  783. HRESULT hr;
  784. LPOLESTR p = T2OLE_EX((LPTSTR)pszDate, _ATL_SAFE_ALLOCA_DEF_THRESHOLD);
  785. #ifndef _UNICODE
  786. if( p == NULL )
  787. {
  788. m_dt = 0;
  789. m_status = invalid;
  790. return false;
  791. }
  792. #endif // _UNICODE
  793. if (FAILED(hr = VarDateFromStr( p, lcid, dwFlags, &m_dt )))
  794. {
  795. if (hr == DISP_E_TYPEMISMATCH)
  796. {
  797. // Can't convert string to date, set 0 and invalidate
  798. m_dt = 0;
  799. m_status = invalid;
  800. return false;
  801. }
  802. else if (hr == DISP_E_OVERFLOW)
  803. {
  804. // Can't convert string to date, set -1 and invalidate
  805. m_dt = -1;
  806. m_status = invalid;
  807. return false;
  808. }
  809. else
  810. {
  811. ATLTRACE(atlTraceTime, 0, _T("\nCOleDateTime VarDateFromStr call failed.\n\t"));
  812. // Can't convert string to date, set -1 and invalidate
  813. m_dt = -1;
  814. m_status = invalid;
  815. return false;
  816. }
  817. }
  818. m_status = valid;
  819. return true;
  820. }
  821. #ifdef _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  822. inline CString COleDateTimeSpan::Format(_In_z_ LPCTSTR pFormat) const
  823. {
  824. // If null, return empty string
  825. if (GetStatus() == null)
  826. return _T("");
  827. CTimeSpan tmp(GetDays(), GetHours(), GetMinutes(), GetSeconds());
  828. return tmp.Format(pFormat);
  829. }
  830. #if defined(_UNICODE) || !defined(_CSTRING_DISABLE_NARROW_WIDE_CONVERSION)
  831. inline CString COleDateTime::Format(
  832. _In_ DWORD dwFlags,
  833. _In_ LCID lcid) const
  834. {
  835. // If null, return empty string
  836. if (GetStatus() == null)
  837. return _T("");
  838. // If invalid, return DateTime global string
  839. if (GetStatus() == invalid)
  840. {
  841. CString str;
  842. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  843. return str;
  844. return szInvalidDateTime;
  845. }
  846. CComBSTR bstr;
  847. if (FAILED(::VarBstrFromDate(m_dt, lcid, dwFlags, &bstr)))
  848. {
  849. CString str;
  850. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  851. return str;
  852. return szInvalidDateTime;
  853. }
  854. CString tmp = CString(bstr);
  855. return tmp;
  856. }
  857. #endif
  858. inline CString COleDateTime::Format(_In_z_ LPCTSTR pFormat) const
  859. {
  860. ATLENSURE_THROW(pFormat != NULL, E_INVALIDARG);
  861. // If null, return empty string
  862. if(GetStatus() == null)
  863. return _T("");
  864. // If invalid, return DateTime global string
  865. if(GetStatus() == invalid)
  866. {
  867. CString str;
  868. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  869. return str;
  870. return szInvalidDateTime;
  871. }
  872. UDATE ud;
  873. if (S_OK != VarUdateFromDate(m_dt, 0, &ud))
  874. {
  875. CString str;
  876. if(str.LoadString(ATL_IDS_DATETIME_INVALID))
  877. return str;
  878. return szInvalidDateTime;
  879. }
  880. struct tm tmTemp;
  881. tmTemp.tm_sec = ud.st.wSecond;
  882. tmTemp.tm_min = ud.st.wMinute;
  883. tmTemp.tm_hour = ud.st.wHour;
  884. tmTemp.tm_mday = ud.st.wDay;
  885. tmTemp.tm_mon = ud.st.wMonth - 1;
  886. tmTemp.tm_year = ud.st.wYear - 1900;
  887. tmTemp.tm_wday = ud.st.wDayOfWeek;
  888. tmTemp.tm_yday = ud.wDayOfYear - 1;
  889. tmTemp.tm_isdst = 0;
  890. CString strDate;
  891. LPTSTR lpszTemp = strDate.GetBufferSetLength(256);
  892. _tcsftime(lpszTemp, strDate.GetLength(), pFormat, &tmTemp);
  893. strDate.ReleaseBuffer();
  894. return strDate;
  895. }
  896. inline CString COleDateTimeSpan::Format(_In_ UINT nFormatID) const
  897. {
  898. CString strFormat;
  899. if (!strFormat.LoadString(nFormatID))
  900. AtlThrow(E_INVALIDARG);
  901. return Format(strFormat);
  902. }
  903. inline CString COleDateTime::Format(_In_ UINT nFormatID) const
  904. {
  905. CString strFormat;
  906. ATLENSURE(strFormat.LoadString(nFormatID));
  907. return Format(strFormat);
  908. }
  909. inline COleDateTime::COleDateTime(_In_ const DBTIMESTAMP& dbts)
  910. {
  911. SYSTEMTIME st;
  912. ::ZeroMemory(&st, sizeof(SYSTEMTIME));
  913. st.wYear = WORD(dbts.year);
  914. st.wMonth = WORD(dbts.month);
  915. st.wDay = WORD(dbts.day);
  916. st.wHour = WORD(dbts.hour);
  917. st.wMinute = WORD(dbts.minute);
  918. st.wSecond = WORD(dbts.second);
  919. m_status = ::SystemTimeToVariantTime(&st, &m_dt) ? valid : invalid;
  920. }
  921. inline _Success_(return != false) bool COleDateTime::GetAsDBTIMESTAMP(_Out_ DBTIMESTAMP& dbts) const
  922. {
  923. UDATE ud;
  924. if (S_OK != VarUdateFromDate(m_dt, 0, &ud))
  925. return false;
  926. dbts.year = (SHORT) ud.st.wYear;
  927. dbts.month = (USHORT) ud.st.wMonth;
  928. dbts.day = (USHORT) ud.st.wDay;
  929. dbts.hour = (USHORT) ud.st.wHour;
  930. dbts.minute = (USHORT) ud.st.wMinute;
  931. dbts.second = (USHORT) ud.st.wSecond;
  932. dbts.fraction = 0;
  933. return true;
  934. }
  935. #endif // _ATL_USE_WINAPI_FAMILY_DESKTOP_APP
  936. } // namespace ATL
  937. #pragma pack(pop)
  938. #pragma warning(pop)
  939. #endif // __ATLCOMTIME_H__