home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / timecore.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  8KB  |  346 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_AUX_SEG
  14. #pragma code_seg(AFX_AUX_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CTime - absolute time
  24.  
  25. CTime::CTime(int nYear, int nMonth, int nDay, int nHour, int nMin, int nSec,
  26.     int nDST)
  27. {
  28.     struct tm atm;
  29.     atm.tm_sec = nSec;
  30.     atm.tm_min = nMin;
  31.     atm.tm_hour = nHour;
  32.     ASSERT(nDay >= 1 && nDay <= 31);
  33.     atm.tm_mday = nDay;
  34.     ASSERT(nMonth >= 1 && nMonth <= 12);
  35.     atm.tm_mon = nMonth - 1;        // tm_mon is 0 based
  36.     ASSERT(nYear >= 1900);
  37.     atm.tm_year = nYear - 1900;     // tm_year is 1900 based
  38.     atm.tm_isdst = nDST;
  39.     m_time = mktime(&atm);
  40.     ASSERT(m_time != -1);       // indicates an illegal input time
  41. }
  42.  
  43. CTime::CTime(WORD wDosDate, WORD wDosTime, int nDST)
  44. {
  45.     struct tm atm;
  46.     atm.tm_sec = (wDosTime & ~0xFFE0) << 1;
  47.     atm.tm_min = (wDosTime & ~0xF800) >> 5;
  48.     atm.tm_hour = wDosTime >> 11;
  49.  
  50.     atm.tm_mday = wDosDate & ~0xFFE0;
  51.     atm.tm_mon = ((wDosDate & ~0xFE00) >> 5) - 1;
  52.     atm.tm_year = (wDosDate >> 9) + 80;
  53.     atm.tm_isdst = nDST;
  54.     m_time = mktime(&atm);
  55.     ASSERT(m_time != -1);       // indicates an illegal input time
  56. }
  57.  
  58. CTime::CTime(const SYSTEMTIME& sysTime, int nDST)
  59. {
  60.     if (sysTime.wYear < 1900)
  61.     {
  62.         time_t time0 = 0L;
  63.         CTime timeT(time0);
  64.         *this = timeT;
  65.     }
  66.     else
  67.     {
  68.         CTime timeT(
  69.             (int)sysTime.wYear, (int)sysTime.wMonth, (int)sysTime.wDay,
  70.             (int)sysTime.wHour, (int)sysTime.wMinute, (int)sysTime.wSecond,
  71.             nDST);
  72.         *this = timeT;
  73.     }
  74. }
  75.  
  76. CTime::CTime(const FILETIME& fileTime, int nDST)
  77. {
  78.     // first convert file time (UTC time) to local time
  79.     FILETIME localTime;
  80.     if (!FileTimeToLocalFileTime(&fileTime, &localTime))
  81.     {
  82.         m_time = 0;
  83.         return;
  84.     }
  85.  
  86.     // then convert that time to system time
  87.     SYSTEMTIME sysTime;
  88.     if (!FileTimeToSystemTime(&localTime, &sysTime))
  89.     {
  90.         m_time = 0;
  91.         return;
  92.     }
  93.  
  94.     // then convert the system time to a time_t (C-runtime local time)
  95.     CTime timeT(sysTime, nDST);
  96.     *this = timeT;
  97. }
  98.  
  99. CTime PASCAL CTime::GetCurrentTime()
  100. // return the current system time
  101. {
  102.     return CTime(::time(NULL));
  103. }
  104.  
  105. struct tm* CTime::GetGmtTm(struct tm* ptm) const
  106. {
  107.     if (ptm != NULL)
  108.     {
  109.         *ptm = *gmtime(&m_time);
  110.         return ptm;
  111.     }
  112.     else
  113.         return gmtime(&m_time);
  114. }
  115.  
  116. struct tm* CTime::GetLocalTm(struct tm* ptm) const
  117. {
  118.     if (ptm != NULL)
  119.     {
  120.         struct tm* ptmTemp = localtime(&m_time);
  121.         if (ptmTemp == NULL)
  122.             return NULL;    // indicates the m_time was not initialized!
  123.  
  124.         *ptm = *ptmTemp;
  125.         return ptm;
  126.     }
  127.     else
  128.         return localtime(&m_time);
  129. }
  130.  
  131. BOOL CTime::GetAsSystemTime(SYSTEMTIME& timeDest) const
  132. {
  133.     struct tm* ptm = GetLocalTm(NULL);
  134.     if (ptm == NULL)
  135.         return FALSE;
  136.  
  137.     timeDest.wYear = (WORD) (1900 + ptm->tm_year);
  138.     timeDest.wMonth = (WORD) (1 + ptm->tm_mon);
  139.     timeDest.wDayOfWeek = (WORD) ptm->tm_wday;
  140.     timeDest.wDay = (WORD) ptm->tm_mday;
  141.     timeDest.wHour = (WORD) ptm->tm_hour;
  142.     timeDest.wMinute = (WORD) ptm->tm_min;
  143.     timeDest.wSecond = (WORD) ptm->tm_sec;
  144.     timeDest.wMilliseconds = 0;
  145.  
  146.     return TRUE;
  147. }
  148.  
  149.  
  150. #ifdef _DEBUG
  151. CDumpContext& AFXAPI operator <<(CDumpContext& dc, CTime time)
  152. {
  153.     char* psz = ctime(&time.m_time);
  154.     if ((psz == NULL) || (time.m_time == 0))
  155.         return dc << "CTime(invalid #" << time.m_time << ")";
  156.  
  157.     // format it
  158.     psz[24] = '\0';         // nuke newline
  159.     return dc << "CTime(\"" << psz << "\")";
  160. }
  161. #endif
  162.  
  163. CArchive& AFXAPI operator <<(CArchive& ar, CTime time)
  164. {
  165.     return ar << (DWORD) time.m_time;
  166. }
  167.  
  168. CArchive& AFXAPI operator >>(CArchive& ar, CTime& rtime)
  169. {
  170.     return ar >> (DWORD&) rtime.m_time;
  171. }
  172.  
  173. /////////////////////////////////////////////////////////////////////////////
  174. // CTimeSpan - relative time
  175.  
  176. #ifdef _DEBUG
  177. CDumpContext& AFXAPI operator <<(CDumpContext& dc, CTimeSpan timeSpan)
  178. {
  179.     return dc << "CTimeSpan(" << timeSpan.GetDays() << " days, " <<
  180.          timeSpan.GetHours() << " hours, " <<
  181.          timeSpan.GetMinutes() << " minutes and " <<
  182.          timeSpan.GetSeconds() << " seconds)";
  183. }
  184. #endif
  185.  
  186. CArchive& AFXAPI operator <<(CArchive& ar, CTimeSpan timeSpan)
  187. {
  188.     return ar << (DWORD) timeSpan.m_timeSpan;
  189. }
  190.  
  191. CArchive& AFXAPI operator >>(CArchive& ar, CTimeSpan& rtimeSpan)
  192. {
  193.     return ar >> (DWORD&) rtimeSpan.m_timeSpan;
  194. }
  195.  
  196.  
  197. /////////////////////////////////////////////////////////////////////////////
  198. // String formatting
  199.  
  200. #define maxTimeBufferSize       128
  201.     // Verifies will fail if the needed buffer size is too large
  202.  
  203. #ifdef _UNICODE
  204. #endif
  205.  
  206. CString CTimeSpan::Format(LPCTSTR pFormat) const
  207. // formatting timespans is a little trickier than formatting CTimes
  208. //  * we are only interested in relative time formats, ie. it is illegal
  209. //      to format anything dealing with absolute time (i.e. years, months,
  210. //         day of week, day of year, timezones, ...)
  211. //  * the only valid formats:
  212. //      %D - # of days -- NEW !!!
  213. //      %H - hour in 24 hour format
  214. //      %M - minute (0-59)
  215. //      %S - seconds (0-59)
  216. //      %% - percent sign
  217. {
  218.     TCHAR szBuffer[maxTimeBufferSize];
  219.     TCHAR ch;
  220.     LPTSTR pch = szBuffer;
  221.  
  222.     while ((ch = *pFormat++) != '\0')
  223.     {
  224.         ASSERT(pch < &szBuffer[maxTimeBufferSize]);
  225.         if (ch == '%')
  226.         {
  227.             switch (ch = *pFormat++)
  228.             {
  229.             default:
  230.                 ASSERT(FALSE);      // probably a bad format character
  231.             case '%':
  232.                 *pch++ = ch;
  233.                 break;
  234.             case 'D':
  235.                 pch += wsprintf(pch, _T("%ld"), GetDays());
  236.                 break;
  237.             case 'H':
  238.                 pch += wsprintf(pch, _T("%02d"), GetHours());
  239.                 break;
  240.             case 'M':
  241.                 pch += wsprintf(pch, _T("%02d"), GetMinutes());
  242.                 break;
  243.             case 'S':
  244.                 pch += wsprintf(pch, _T("%02d"), GetSeconds());
  245.                 break;
  246.             }
  247.         }
  248.         else
  249.         {
  250.             *pch++ = ch;
  251.             if (_istlead(ch))
  252.             {
  253.                 ASSERT(pch < &szBuffer[maxTimeBufferSize]);
  254.                 *pch++ = *pFormat++;
  255.             }
  256.         }
  257.     }
  258.  
  259.     *pch = '\0';
  260.     return szBuffer;
  261. }
  262.  
  263. CString CTimeSpan::Format(UINT nFormatID) const
  264. {
  265.     CString strFormat;
  266.     VERIFY(strFormat.LoadString(nFormatID) != 0);
  267.     return Format(strFormat);
  268. }
  269.  
  270. CString CTime::Format(LPCTSTR pFormat) const
  271. {
  272.     TCHAR szBuffer[maxTimeBufferSize];
  273.  
  274.     struct tm* ptmTemp = localtime(&m_time);
  275.     if (ptmTemp == NULL ||
  276.         !_tcsftime(szBuffer, _countof(szBuffer), pFormat, ptmTemp))
  277.         szBuffer[0] = '\0';
  278.     return szBuffer;
  279. }
  280.  
  281. CString CTime::FormatGmt(LPCTSTR pFormat) const
  282. {
  283.     TCHAR szBuffer[maxTimeBufferSize];
  284.  
  285.     struct tm* ptmTemp = gmtime(&m_time);
  286.     if (ptmTemp == NULL ||
  287.         !_tcsftime(szBuffer, _countof(szBuffer), pFormat, ptmTemp))
  288.         szBuffer[0] = '\0';
  289.     return szBuffer;
  290. }
  291.  
  292. CString CTime::Format(UINT nFormatID) const
  293. {
  294.     CString strFormat;
  295.     VERIFY(strFormat.LoadString(nFormatID) != 0);
  296.     return Format(strFormat);
  297. }
  298.  
  299. CString CTime::FormatGmt(UINT nFormatID) const
  300. {
  301.     CString strFormat;
  302.     VERIFY(strFormat.LoadString(nFormatID) != 0);
  303.     return FormatGmt(strFormat);
  304. }
  305.  
  306. #ifdef _UNICODE
  307. // These functions are provided for compatibility with MFC 3.x
  308. CString CTime::Format(LPCSTR pFormat) const
  309. {
  310.     CString strFormat(pFormat);
  311.     return Format((LPCTSTR)strFormat);
  312. }
  313.  
  314. CString CTime::FormatGmt(LPCSTR pFormat) const
  315. {
  316.     CString strFormat(pFormat);
  317.     return FormatGmt((LPCTSTR)strFormat);
  318. }
  319.  
  320. CString CTimeSpan::Format(LPCSTR pFormat) const
  321. {
  322.     CString strFormat = pFormat;
  323.     return Format((LPCTSTR)strFormat);
  324. }
  325. #endif // _UNICODE
  326.  
  327. ////////////////////////////////////////////////////////////////////////////
  328. // out-of-line inlines for binary compatibility
  329.  
  330. #ifdef _AFXDLL
  331. #ifndef _DEBUG
  332.  
  333. CTime::CTime()
  334.     { }
  335.  
  336. CTime::CTime(const CTime& timeSrc)
  337.     { m_time = timeSrc.m_time; }
  338.  
  339. CTimeSpan::CTimeSpan()
  340.     { }
  341.  
  342. #endif
  343. #endif
  344.  
  345. /////////////////////////////////////////////////////////////////////////////
  346.