/plugins/winamp/comdate.h
C Header | 1097 lines | 771 code | 199 blank | 127 comment | 80 complexity | 0f8edcefa7a954b8b2fa2cb49a214399 MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause
- // comdate.h
- /////////////////////////////////////////////////////////////////////////////
- // Copyright (c) 1998-2000 Chris Sells
- // All rights reserved.
- //
- // NO WARRANTIES ARE EXTENDED. USE AT YOUR OWN RISK.
- //
- // To contact the author with suggestions or comments, use csells@sellsbrothers.com.
- /////////////////////////////////////////////////////////////////////////////
- // History:
- // 9/27/01 - Dropped in operator SYSTEMTIME() and operator FILETIME() from
- // Scott Zionic [Scott.Zionic@petersweb.com]. Thanks, Scott.
- // 4/9/01 - Implemented operator time_t() and operator struct tm() as per
- // Shawn Wildermuth's request.
- // 2/8/01 - Fixed a rounding bug in CComSpan reported by Ralf Mohaupt
- // [r.mohaupt@lit.lineas.de].
- // 11/4/00 - Moved everything to the header file for convenience.
- // 4/13/00 - Sudhakar M [msudhakar@yahoo.com] contributed
- // CComDATE(const struct tm& tmSrc), from which I also extrapolated
- // CComDATE::operator=(const struct tm& tmSrc).
- // 3/10/00 - Inspired by Eric White [EricW@DATA-TECH.COM] to add an
- // operator DBTIMESTAMP using his implementation. Also added
- // extra ctor, operator= and conversion operators for other date/time
- // formats, but haven't implemented all of them yet.
- // Inspired by Artyom Tyazhelov [artyom6@hotmail.com] to
- // leave current time alone when calling SetDate and leaving current
- // date alone when calling SetTime.
- // 1/15/00 - Fixed a 2038 bug in Now. Thanks Michael Entin [entin@swusa.com].
- // 7/14/99 - Fixed a linker problem w/ some inline functions release
- // builds. Thanks to David Maw [David.Maw@unisys.com] for
- // first pointing it out.
- // 6/9/99 - Fixed a problem in Maketm where tm_isdst was not being set
- // (as is required by the CRT). Thanks to Jim Hoffman
- // [JHoffman@Enerx.com] for pointing it out.
- // 4/18/99 - Fixed a problem in Format to provide a work-around in the
- // VC6 implementation of wcsftime. Thanks for Joe O'Leary for
- // pointing it out.
- // Even better, Joe also contributed FormatDate and FormatTime
- // to wrap the National Language Support functions GetTimeFormat()
- // and GetDateFormat(). Thanks, Joe!
- // Also, Juan Rivera (juanc@kodak.com) pointed out a missing operator=
- // declaration. Thanks, Juan.
- // 12/24/98 - Based on a suggestion by Ronald Laeremans [RonaldL@mvps.org],
- // replaced all of the manual Maketm code w/ VariantToSystemTime.
- // Also updated MakeDATE to use SystemTimeToVariantTime. Thanks, Ron!
- // 12/23/98 - Fixed a bug Ward pointed out in CComDATE::operator=(const time_t&).
- // 12/21/98 - Ward Fuller <wfuller@tsisoft.com> pointed out a BSTR leak in
- // the Format implementation. It's plugged. Thanks, Ward!
- // 12/21/98 - Initial release.
- /////////////////////////////////////////////////////////////////////////////
- // The file provides two class for use with dates and times under Windows.
- //
- // CComDATE: Wraps the COM DATE type, providing conversions from VARIANT,
- // DATE, ANSI string, UNICODE string, time_t, SYSTEMTIME, FILETIME,
- // DOS time and DBTIMESTAMP data types.
- //
- // CComSpan: Represents the result of subtracting one CComDATE from another.
- // Useful for time/date math.
- //
- // NOTE: This usage of these classes are based loosely on the MFC classes
- // COleDateTime and COleDateTimeSpan. However, the implementation is 99% mine.
-
- #pragma once
- #ifndef __COMDATE_H__
- #define __COMDATE_H__
-
- #include <time.h>
- #include <limits.h>
- #include <tchar.h>
- #include <math.h> // ceil, floor and modf
- #include <winnls.h>
- #include <OAIDL.H>
- #include <crtdbg.h>
-
- /////////////////////////////////////////////////////////////////////////////
- // CComDATE class
-
- class CComSpan; // Forward declaration
-
- class CComDATE
- {
- public:
- static CComDATE Now();
- static bool IsValidDate(const DATE& dt);
-
- CComDATE();
- CComDATE(const CComDATE& dtSrc);
- CComDATE(const VARIANT& varSrc);
- CComDATE(DATE dtSrc);
- CComDATE(const char* pszSrc);
- CComDATE(const wchar_t* pszSrc);
- CComDATE(time_t timeSrc);
- CComDATE(const struct tm& tmSrc);
- CComDATE(const SYSTEMTIME& systimeSrc);
- CComDATE(const FILETIME& filetimeSrc);
- CComDATE(long nYear, long nMonth, long nDay, long nHour = 0, long nMin = 0, long nSec = 0);
- CComDATE(WORD wDosDate, WORD wDosTime);
-
- #ifdef __oledb_h__
- CComDATE(const DBTIMESTAMP& dbts);
- #endif
-
- public:
- bool IsValid() const;
- long Year() const;
- long Month() const; // month of year (1 = Jan)
- long Day() const; // day of month (1-31)
- long Hour() const; // hour in day (0-23)
- long Minute() const; // minute in hour (0-59)
- long Second() const; // second in minute (0-59)
- long DayOfWeek() const; // 1=Sun, 2=Mon, ..., 7=Sat
- long DayOfYear() const; // days since start of year, Jan 1 = 1
-
- bool IsLeapYear() const; // Whether it's a leap year or not
- bool IsNoon() const; // Whether it's 12:00:00pm or not
- bool IsMidnight() const; // Whether it's 12:00:00am or not
-
- // Operations
- public:
- const CComDATE& operator=(const CComDATE& dtSrc);
- const CComDATE& operator=(const VARIANT& varSrc);
- const CComDATE& operator=(DATE dtSrc);
- const CComDATE& operator=(const char* pszSrc);
- const CComDATE& operator=(const wchar_t* pszSrc);
-
- const CComDATE& operator=(const time_t& timeSrc);
- const CComDATE& operator=(const struct tm& tmSrc);
- const CComDATE& operator=(const SYSTEMTIME& systimeSrc);
- const CComDATE& operator=(const FILETIME& filetimeSrc);
-
- #ifdef __oledb_h__
- const CComDATE& CComDATE::operator=(const DBTIMESTAMP& dbts);
- #endif
-
- bool operator==(const CComDATE& date) const;
- bool operator!=(const CComDATE& date) const;
- bool operator<(const CComDATE& date) const;
- bool operator>(const CComDATE& date) const;
- bool operator<=(const CComDATE& date) const;
- bool operator>=(const CComDATE& date) const;
-
- // Date math
- const CComDATE& operator+=(const CComSpan& span);
- const CComDATE& operator-=(const CComSpan& span);
-
- friend CComDATE operator+(const CComDATE& date, const CComSpan& span);
- friend CComDATE operator-(const CComDATE& date, const CComSpan& span);
- friend CComDATE operator+(const CComSpan& span, const CComDATE& date);
- friend CComSpan operator-(const CComDATE& date1, const CComDATE& date2);
-
- operator DATE() const;
- DATE* operator&();
-
- operator VARIANT() const;
- operator time_t() const;
- operator struct tm() const;
- operator SYSTEMTIME() const;
- operator FILETIME() const;
- #ifdef __oledb_h__
- operator DBTIMESTAMP() const;
- #endif
-
- bool SetDateTime(long nYear, long nMonth, long nDay, long nHour, long nMin, long nSec);
- bool SetDate(long nYear, long nMonth, long nDay);
- bool SetTime(long nHour, long nMin, long nSec);
- bool ParseDateTime(const char* lpszDate, DWORD dwFlags = 0, LCID lcid = LANG_USER_DEFAULT);
- bool ParseDateTime(const wchar_t* lpszDate, DWORD dwFlags = 0, LCID lcid = LANG_USER_DEFAULT);
-
- // Formatting
- LPTSTR Format(LPTSTR pszOut, DWORD dwFlags = 0, LCID lcid = LANG_USER_DEFAULT) const;
- LPTSTR Format(LPTSTR pszOut, LPCTSTR lpszFormat) const;
- #ifdef __ATLCOM_H__
- LPTSTR Format(LPTSTR pszOut, UINT nFormatID, HINSTANCE hinst = _Module.GetResourceInstance()) const;
- #else
- LPTSTR Format(LPTSTR pszOut, UINT nFormatID, HINSTANCE hinst = GetModuleHandle(0)) const;
- #endif
-
- // Formatting using National Language Support functions GetTimeFormat() and GetDateFormat()
- LPTSTR FormatTime(LPTSTR pszOut, LPCTSTR szFmt=NULL, DWORD dwFlags=0, LCID lcid=LOCALE_USER_DEFAULT) const;
- LPTSTR FormatDate(LPTSTR pszOut, LPCTSTR szFmt=NULL, DWORD dwFlags=0, LCID lcid=LOCALE_USER_DEFAULT) const;
-
- protected:
- enum
- {
- COMDATE_ERROR = INT_MIN,
- MIN_DATE = -657434L, // About year 100
- MAX_DATE = 2958465L, // About year 9999
- INVALID_DATE = (MIN_DATE-1), // Used to indicate invalid date
- };
-
- protected:
- DATE m_date;
-
- protected:
- void Invalidate();
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // CComSpan class
-
- class CComSpan
- {
- public:
- CComSpan();
- CComSpan(double dblSpanSrc);
- CComSpan(const CComSpan& dateSpanSrc);
- CComSpan(long nDays, long nHours = 0, long nMins = 0, long nSecs = 0);
-
- bool IsValid() const;
-
- double TotalDays() const; // span in days (about -3.65e6 to 3.65e6)
- double TotalHours() const; // span in hours (about -8.77e7 to 8.77e6)
- double TotalMinutes() const; // span in minutes (about -5.26e9 to 5.26e9)
- double TotalSeconds() const; // span in seconds (about -3.16e11 to 3.16e11)
-
- long Days() const; // component days in span
- long Hours() const; // component hours in span (-23 to 23)
- long Minutes() const; // component minutes in span (-59 to 59)
- long Seconds() const; // component seconds in span (-59 to 59)
-
- public:
- const CComSpan& operator=(double dblSpanSrc);
- const CComSpan& operator=(const CComSpan& dateSpanSrc);
-
- bool operator==(const CComSpan& dateSpan) const;
- bool operator!=(const CComSpan& dateSpan) const;
- bool operator<(const CComSpan& dateSpan) const;
- bool operator>(const CComSpan& dateSpan) const;
- bool operator<=(const CComSpan& dateSpan) const;
- bool operator>=(const CComSpan& dateSpan) const;
-
- // Math
- const CComSpan& operator+=(const CComSpan& rhs);
- const CComSpan& operator-=(const CComSpan& rhs);
- CComSpan operator-() const;
-
- friend CComSpan operator+(const CComSpan& span1, const CComSpan& span2);
- friend CComSpan operator-(const CComSpan& span1, const CComSpan& span2);
-
- operator double() const;
-
- void SetSpan(long nDays, long nHours, long nMins, long nSecs);
-
- protected:
- enum
- {
- MAX_SPAN = 3615897L,
- MIN_SPAN = -MAX_SPAN,
- INVALID_SPAN = (MIN_SPAN-1), // Used to indicate invalid span
- };
-
- protected:
- double m_span;
-
- protected:
- void Invalidate();
- };
-
- /////////////////////////////////////////////////////////////////////////////
- // CComDATE inline implementations
-
- inline bool CComDATE::IsValidDate(const DATE& dt)
- {
- // About year 100 to about 9999
- return (dt >= MIN_DATE && dt <= MAX_DATE);
- }
-
- inline CComDATE CComDATE::Now()
- {
- SYSTEMTIME sysTime;
- GetLocalTime(&sysTime);
- return CComDATE(sysTime);
- }
-
- inline CComDATE::CComDATE()
- { Invalidate(); }
-
- inline CComDATE::CComDATE(const CComDATE& dtSrc)
- { m_date = dtSrc.m_date; }
-
- inline CComDATE::CComDATE(const VARIANT& varSrc)
- { *this = varSrc; }
-
- inline CComDATE::CComDATE(DATE dtSrc)
- { m_date = dtSrc; }
-
- inline CComDATE::CComDATE(const char* pszSrc)
- { ParseDateTime(pszSrc); }
-
- inline CComDATE::CComDATE(const wchar_t* pszSrc)
- { ParseDateTime(pszSrc); }
-
- inline CComDATE::CComDATE(time_t timeSrc)
- { *this = timeSrc; }
-
- inline CComDATE::CComDATE(const struct tm& tmSrc)
- {
- SetDateTime(tmSrc.tm_year + 1900,
- tmSrc.tm_mon + 1,
- tmSrc.tm_mday,
- tmSrc.tm_hour,
- tmSrc.tm_min,
- tmSrc.tm_sec);
- }
-
- inline CComDATE::CComDATE(const SYSTEMTIME& systimeSrc)
- { *this = systimeSrc; }
-
- inline CComDATE::CComDATE(const FILETIME& filetimeSrc)
- { *this = filetimeSrc; }
-
- inline CComDATE::CComDATE(long nYear, long nMonth, long nDay, long nHour, long nMin, long nSec)
- { SetDateTime(nYear, nMonth, nDay, nHour, nMin, nSec); }
-
- inline CComDATE::CComDATE(WORD wDosDate, WORD wDosTime)
- { if( !DosDateTimeToVariantTime(wDosDate, wDosTime, &m_date) ) Invalidate(); }
-
- inline const CComDATE& CComDATE::operator=(const CComDATE& dtSrc)
- { m_date = dtSrc.m_date; return *this; }
-
- inline const CComDATE& CComDATE::operator=(const char* pszSrc)
- { ParseDateTime(pszSrc); return *this; }
-
- inline const CComDATE& CComDATE::operator=(const wchar_t* pszSrc)
- { ParseDateTime(pszSrc); return *this; }
-
- inline bool CComDATE::operator==(const CComDATE& date) const
- { return (m_date == date.m_date); }
-
- inline bool CComDATE::operator!=(const CComDATE& date) const
- { return (m_date != date.m_date); }
-
- inline CComDATE::operator DATE() const
- { return m_date; }
-
- inline DATE* CComDATE::operator&()
- { return &m_date; }
-
- inline bool CComDATE::SetDate(long nYear, long nMonth, long nDay)
- { return SetDateTime(nYear, nMonth, nDay, Hour(), Minute(), Second()); }
-
- inline bool CComDATE::SetTime(long nHour, long nMin, long nSec)
- { return SetDateTime(Year(), Month(), Day(), nHour, nMin, nSec); }
-
- inline const CComDATE& CComDATE::operator+=(const CComSpan& span)
- { *this = *this + span; return *this; }
-
- inline const CComDATE& CComDATE::operator-=(const CComSpan& span)
- { *this = *this - span; return *this; }
-
- inline bool CComDATE::IsValid() const
- { return IsValidDate(m_date); }
-
- inline void CComDATE::Invalidate()
- { m_date = INVALID_DATE; }
-
- #ifdef __oledb_h__
- inline CComDATE::CComDATE(const DBTIMESTAMP& dbts)
- { SetDateTime(dbts.year, dbts.month, dbts.day, dbts.hour, dbts.minute, dbts.second); }
-
- inline const CComDATE& CComDATE::operator=(const DBTIMESTAMP& dbts)
- { SetDateTime(dbts.year, dbts.month, dbts.day, dbts.hour, dbts.minute, dbts.second); return *this; }
-
- #endif // __oledb_h__
-
- /////////////////////////////////////////////////////////////////////////////
- // CComSpan inline implementations
-
- inline CComSpan::CComSpan()
- { Invalidate(); }
-
- inline CComSpan::CComSpan(double db) : m_span(db) {}
-
- inline CComSpan::CComSpan(const CComSpan& rhs)
- { m_span = rhs.m_span; }
-
- inline CComSpan::CComSpan(long nDays, long nHours, long nMins, long nSecs)
- { SetSpan(nDays, nHours, nMins, nSecs); }
-
- inline const CComSpan& CComSpan::operator=(double db)
- { m_span = db; return *this; }
-
- inline const CComSpan& CComSpan::operator=(const CComSpan& span)
- { m_span = span.m_span; return *this; }
-
- inline double CComSpan::TotalDays() const
- { _ASSERTE(IsValid()); return m_span; }
-
- inline double CComSpan::TotalHours() const
- { _ASSERTE(IsValid()); return m_span * 24; }
-
- inline double CComSpan::TotalMinutes() const
- { _ASSERTE(IsValid()); return m_span * 24 * 60; }
-
- inline double CComSpan::TotalSeconds() const
- { _ASSERTE(IsValid()); return m_span * 24 * 60 * 60; }
-
- inline long CComSpan::Days() const
- { _ASSERTE(IsValid()); return (long)m_span; }
-
- inline bool CComSpan::operator==(const CComSpan& rhs) const
- { return m_span == rhs.m_span; }
-
- inline bool CComSpan::operator!=(const CComSpan& rhs) const
- { return m_span != rhs.m_span; }
-
- inline bool CComSpan::operator<(const CComSpan& rhs) const
- { return m_span < rhs.m_span; }
-
- inline bool CComSpan::operator>(const CComSpan& rhs) const
- { return m_span > rhs.m_span; }
-
- inline bool CComSpan::operator<=(const CComSpan& rhs) const
- { return m_span <= rhs.m_span; }
-
- inline bool CComSpan::operator>=(const CComSpan& rhs) const
- { return m_span >= rhs.m_span; }
-
- inline const CComSpan& CComSpan::operator+=(const CComSpan& rhs)
- { return (*this = *this + rhs); }
-
- inline const CComSpan& CComSpan::operator-=(const CComSpan& rhs)
- { return (*this = *this - rhs); }
-
- inline CComSpan CComSpan::operator-() const
- { return CComSpan(-m_span); }
-
- inline CComSpan::operator double() const
- { return m_span; }
-
- inline bool CComSpan::IsValid() const
- { return (m_span >= MIN_SPAN && m_span <= MAX_SPAN); }
-
- inline void CComSpan::Invalidate()
- { m_span = INVALID_SPAN; }
-
- /////////////////////////////////////////////////////////////////////////////
- // CComDATE class helper definitions
-
- #define HALF_SECOND 1.0/172800.0 // Half a second, expressed in days
-
- bool MakeDATE(DATE* pdtDest, WORD wYear, WORD wMonth, WORD wDay, WORD wHour, WORD wMinute, WORD wSecond);
- bool Maketm(struct tm* ptmDest, DATE dtSrc);
- double DATEAsDouble(DATE dtSrc);
- DATE MakeDATE(double dbSrc);
-
- /////////////////////////////////////////////////////////////////////////////
- // CComDATE class
-
- inline
- long CComDATE::Year() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_year + 1900;
- return COMDATE_ERROR;
- }
-
- inline
- long CComDATE::Month() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_mon + 1;
- return COMDATE_ERROR;
- }
-
- inline
- long CComDATE::Day() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_mday;
- return COMDATE_ERROR;
- }
-
- inline
- long CComDATE::Hour() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_hour;
- return COMDATE_ERROR;
- }
-
- inline
- long CComDATE::Minute() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_min;
- return COMDATE_ERROR;
- }
-
- inline
- long CComDATE::Second() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_sec;
- return COMDATE_ERROR;
- }
-
- inline
- long CComDATE::DayOfWeek() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_wday + 1;
- return COMDATE_ERROR;
- }
-
- inline
- long CComDATE::DayOfYear() const
- {
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) ) return tmDest.tm_yday + 1;
- return COMDATE_ERROR;
- }
-
- inline
- bool CComDATE::IsLeapYear() const
- {
- long year = Year();
- return ((year != COMDATE_ERROR) && ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0));
- }
-
- inline
- bool CComDATE::IsNoon() const
- {
- return Hour() == 12 && Minute() == 0 && Second() == 0;
- }
-
- inline
- bool CComDATE::IsMidnight() const
- {
- return Hour() == 0 && Minute() == 0 && Second() == 0;
- }
-
- inline
- const CComDATE& CComDATE::operator=(const VARIANT& varSrc)
- {
- if( varSrc.vt == VT_DATE )
- {
- m_date = varSrc.date;
- }
- else
- {
- VARIANT varDest = { 0 };
- if( SUCCEEDED(VariantChangeType(&varDest, const_cast<VARIANT*>(&varSrc), 0, VT_DATE)) )
- {
- m_date = varDest.date;
- VariantClear(&varDest);
- }
- else
- {
- Invalidate();
- }
- }
-
- return *this;
- }
-
- inline
- const CComDATE& CComDATE::operator=(DATE dtSrc)
- {
- m_date = dtSrc;
- return *this;
- }
-
- inline
- const CComDATE& CComDATE::operator=(const time_t& tmSrc)
- {
- // Convert time_t to struct tm
- tm *ptm = localtime(&tmSrc);
-
- if( !ptm ||
- !MakeDATE(&m_date,
- (WORD)(ptm->tm_year + 1900),
- (WORD)(ptm->tm_mon + 1),
- (WORD)ptm->tm_mday,
- (WORD)ptm->tm_hour,
- (WORD)ptm->tm_min,
- (WORD)ptm->tm_sec) )
- {
- // Local time must have failed (tmSrc before 1/1/70 12am)
- Invalidate();
- }
-
- return *this;
- }
-
- inline
- const CComDATE& CComDATE::operator=(const struct tm& tmSrc)
- {
- SetDateTime(tmSrc.tm_year + 1900,
- tmSrc.tm_mon + 1,
- tmSrc.tm_mday,
- tmSrc.tm_hour,
- tmSrc.tm_min,
- tmSrc.tm_sec);
-
- return *this;
- }
-
- inline
- const CComDATE& CComDATE::operator=(const SYSTEMTIME& systmSrc)
- {
- if( !MakeDATE(&m_date,
- systmSrc.wYear,
- systmSrc.wMonth,
- systmSrc.wDay,
- systmSrc.wHour,
- systmSrc.wMinute,
- systmSrc.wSecond) )
- {
- Invalidate();
- }
-
- return *this;
- }
-
- inline
- const CComDATE& CComDATE::operator=(const FILETIME& ftSrc)
- {
- // Assume UTC FILETIME, so convert to LOCALTIME
- FILETIME ftLocal;
- if( !FileTimeToLocalFileTime( &ftSrc, &ftLocal) )
- {
- #ifdef ATLTRACE
- ATLTRACE("\nFileTimeToLocalFileTime failed. Error = %lu.\n\t", GetLastError());
- #endif
- Invalidate();
- }
- else
- {
- // Take advantage of SYSTEMTIME -> FILETIME conversion
- SYSTEMTIME systime;
-
- // At this polong systime should always be valid, but...
- if( !FileTimeToSystemTime(&ftLocal, &systime) ||
- !MakeDATE(&m_date,
- systime.wYear,
- systime.wMonth,
- systime.wDay,
- systime.wHour,
- systime.wMinute,
- systime.wSecond) )
- {
- Invalidate();
- }
- }
-
- return *this;
- }
-
- inline
- CComDATE::operator VARIANT() const
- {
- VARIANT var = { 0 };
- var.vt = VT_DATE;
- var.date = m_date;
- return var;
- }
-
- inline
- CComDATE::operator time_t() const
- {
- struct tm tmDest;
- if( Maketm(&tmDest, m_date) )
- {
- return mktime(&tmDest);
- }
-
- return -1;
- }
-
- inline
- CComDATE::operator struct tm() const
- {
- struct tm tmDest = { 0 };
- Maketm(&tmDest, m_date);
- return tmDest;
- }
-
- inline
- CComDATE::operator SYSTEMTIME() const
- {
- SYSTEMTIME st = { 0 };
-
- VariantTimeToSystemTime(m_date, &st);
-
- return st;
- }
-
- inline
- CComDATE::operator FILETIME() const
- {
- FILETIME ft = { 0 };
-
- SYSTEMTIME st;
- VariantTimeToSystemTime(m_date, &st);
- SystemTimeToFileTime(&st, &ft);
-
- return ft;
- }
-
- #ifdef __oledb_h__
- inline
- CComDATE::operator DBTIMESTAMP() const
- {
- DBTIMESTAMP dbts = { 0 };
-
- struct tm tmDest;
- if( IsValid() && Maketm(&tmDest, m_date) )
- {
- dbts.day = tmDest.tm_mday;
- dbts.month = tmDest.tm_mon + 1;
- dbts.year = tmDest.tm_year + 1900;
- dbts.hour = tmDest.tm_hour;
- dbts.minute = tmDest.tm_min;
- dbts.second = tmDest.tm_sec;
- }
-
- return dbts;
- }
- #endif
-
- inline
- bool CComDATE::operator<(const CComDATE& date) const
- {
- _ASSERTE(IsValid());
- _ASSERTE(date.IsValid());
-
- // Handle negative dates
- return DATEAsDouble(m_date) < DATEAsDouble(date.m_date);
- }
-
- inline
- bool CComDATE::operator>(const CComDATE& date) const
- {
- _ASSERTE(IsValid());
- _ASSERTE(date.IsValid());
-
- // Handle negative dates
- return DATEAsDouble(m_date) > DATEAsDouble(date.m_date);
- }
-
- inline
- bool CComDATE::operator<=(const CComDATE& date) const
- {
- _ASSERTE(IsValid());
- _ASSERTE(date.IsValid());
-
- // Handle negative dates
- return DATEAsDouble(m_date) <= DATEAsDouble(date.m_date);
- }
-
- inline
- bool CComDATE::operator>=(const CComDATE& date) const
- {
- _ASSERTE(IsValid());
- _ASSERTE(date.IsValid());
-
- // Handle negative dates
- return DATEAsDouble(m_date) >= DATEAsDouble(date.m_date);
- }
-
- inline
- bool CComDATE::SetDateTime(
- long nYear,
- long nMonth,
- long nDay,
- long nHour,
- long nMin,
- long nSec)
- {
- if( !MakeDATE(&m_date, (WORD)nYear, (WORD)nMonth, (WORD)nDay, (WORD)nHour, (WORD)nMin, (WORD)nSec) )
- {
- Invalidate();
- }
-
- return IsValid();
- }
-
- /*inline
- bool CComDATE::ParseDateTime(const char* lpszDate, DWORD dwFlags, LCID lcid)
- {
- USES_CONVERSION;
- return ParseDateTime(A2OLE(lpszDate), dwFlags, lcid);
- }*/
-
- inline
- bool CComDATE::ParseDateTime(const wchar_t* lpszDate, DWORD dwFlags, LCID lcid)
- {
- if( FAILED(VarDateFromStr(const_cast<wchar_t*>(lpszDate), lcid, dwFlags, &m_date)) )
- {
- Invalidate();
- }
-
- return IsValid();
- }
-
- inline
- LPTSTR CComDATE::Format(LPTSTR pszOut, DWORD dwFlags, LCID lcid) const
- {
- *pszOut = 0;
-
- // If invalild, return empty string
- if (!IsValid()) return pszOut;
-
- BSTR bstr = 0;
- if( SUCCEEDED(VarBstrFromDate(m_date, lcid, dwFlags, &bstr)) )
- {
- #ifdef _UNICODE
- wcscpy(pszOut, bstr);
- #else
- wcstombs(pszOut, bstr, wcslen(bstr) + 1);
- #endif
-
- SysFreeString(bstr);
- }
-
- return pszOut;
- }
-
- inline
- LPTSTR CComDATE::Format(LPTSTR pszOut, LPCTSTR pFormat) const
- {
- *pszOut = 0;
-
- // If invalild, return empty string
- struct tm tmDest;
- if (!IsValid() || !Maketm(&tmDest, m_date) ) return pszOut;
-
- // Fill in the buffer, disregard return value as it's not necessary
- // NOTE: 4096 is an arbitrary value picked lower than INT_MAX
- // as the VC6 implementation of wcsftime allocates memory based
- // on the 2nd parameter for some reason.
- _tcsftime(pszOut, 4096, pFormat, &tmDest);
- return pszOut;
- }
-
- inline
- LPTSTR CComDATE::Format(LPTSTR pszOut, UINT nFormatID, HINSTANCE hinst) const
- {
- *pszOut = 0;
-
- TCHAR sz[256];
- if( LoadString(hinst, nFormatID, sz, sizeof(sz)/sizeof(*sz)) )
- {
- return Format(pszOut, sz);
- }
-
- return pszOut;
- }
-
- // The FormatDate and FormatTime functions were provided by Joe O'Leary (joleary@artisoft.com) to
- // wrap he Win32 National Language Support functions ::GetDateFormat() and ::GetTimeFormat().
- // The format strings used here are specified in the on-line help for those functions.
- // The default format is the current user locale.
-
- inline
- LPTSTR CComDATE::FormatDate(LPTSTR pszOut, LPCTSTR szFmt, DWORD dwFlags, LCID lcid) const
- {
- _ASSERTE((szFmt==NULL) || (dwFlags==0));// if format is non-NULL, 'dwFlags' MUST be zero
-
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- *pszOut = NULL;
-
- if ( !VariantTimeToSystemTime(m_date, &st) )
- {
- #ifdef ATLTRACE
- ATLTRACE("\nVariantTimeToSystemTime failed. Error = %lu.\n\t", GetLastError());
- #endif
- }
- else if ( GetDateFormat(lcid, dwFlags, &st, szFmt, pszOut, 255) == 0 )
- {
- #ifdef ATLTRACE
- ATLTRACE("\nGetDateFormat failed. Error = %lu.\n\t", GetLastError());
- #endif
- }
-
- return pszOut;
- }
-
- inline
- LPTSTR CComDATE::FormatTime(LPTSTR pszOut, LPCTSTR szFmt, DWORD dwFlags, LCID lcid) const
- {
- _ASSERTE((szFmt==NULL) || (dwFlags==0));// if format is non-NULL, 'dwFlags' MUST be zero
-
- SYSTEMTIME st;
- memset(&st, 0, sizeof(SYSTEMTIME));
- *pszOut = NULL;
-
- if ( !VariantTimeToSystemTime(m_date, &st) )
- {
- #ifdef ATLTRACE
- ATLTRACE("\nVariantTimeToSystemTime failed. Error = %lu.\n\t", GetLastError());
- #endif
- }
- else if ( GetTimeFormat(lcid, dwFlags, &st, szFmt, pszOut, 255) == 0 )
- {
- #ifdef ATLTRACE
- ATLTRACE("\nGetTimeFormat failed. Error = %lu.\n\t", GetLastError());
- #endif
- }
-
- return pszOut;
- }
-
- inline
- bool Maketm(struct tm* ptmDest, DATE dtSrc)
- {
- SYSTEMTIME st;
- if( !VariantTimeToSystemTime(dtSrc, &st) ) return false;
-
- struct tm& tmDest = *ptmDest; // Convenience
- tmDest.tm_sec = st.wSecond;
- tmDest.tm_min = st.wMinute;
- tmDest.tm_hour = st.wHour;
- tmDest.tm_mday = st.wDay;
- tmDest.tm_mon = st.wMonth - 1;
- tmDest.tm_year = st.wYear - 1900;
- tmDest.tm_wday = st.wDayOfWeek;
- tmDest.tm_isdst = -1; // Force DST checking
- mktime(&tmDest); // Normalize
-
- return true;
- }
-
- inline
- double DATEAsDouble(DATE dt)
- {
- // No problem if positive
- if (dt >= 0) return dt;
-
- // If negative, must convert since negative dates not continuous
- // (examples: -1.25 to -.75, -1.50 to -.50, -1.75 to -.25)
- double temp = ceil(dt);
- return temp - (dt - temp);
- }
-
- inline
- DATE MakeDATE(double dbl)
- {
- // No problem if positive
- if (dbl >= 0) return dbl;
-
- // If negative, must convert since negative dates not continuous
- // (examples: -.75 to -1.25, -.50 to -1.50, -.25 to -1.75)
- double temp = floor(dbl); // dbl is now whole part
- return temp + (temp - dbl);
- }
-
- inline
- bool MakeDATE(
- DATE* pdtDest,
- WORD wYear,
- WORD wMonth,
- WORD wDay,
- WORD wHour,
- WORD wMinute,
- WORD wSecond)
- {
- SYSTEMTIME st = { 0 };
- st.wYear = wYear;
- st.wMonth = wMonth;
- st.wDay = wDay;
- st.wHour = wHour;
- st.wMinute = wMinute;
- st.wSecond = wSecond;
-
- return SystemTimeToVariantTime(&st, pdtDest) ? true : false;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CComSpan class
-
- inline
- long CComSpan::Hours() const
- {
- _ASSERTE(IsValid());
-
- // Truncate days and scale up
- double dbTemp = modf(m_span, &dbTemp);
- return (long)(dbTemp * 24);
- }
-
- inline
- long CComSpan::Minutes() const
- {
- _ASSERTE(IsValid());
-
- // Truncate hours and scale up
- double dbTemp = modf(m_span * 24, &dbTemp);
- return (long)((dbTemp + HALF_SECOND) * 60);
- }
-
- inline
- long CComSpan::Seconds() const
- {
- _ASSERTE(IsValid());
-
- // Truncate minutes and scale up
- double dbTemp = modf(m_span * 24 * 60, &dbTemp);
- return (long)(dbTemp * 60);
- }
-
- inline
- void CComSpan::SetSpan(
- long nDays,
- long nHours,
- long nMins,
- long nSecs)
- {
- // Set date span by breaking longo fractional days (all input ranges valid)
- m_span = nDays +
- ((double)nHours)/24 +
- ((double)nMins)/(24*60) +
- ((double)nSecs)/(24*60*60);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CComDATE/CComSpan math friend functions
-
- // date2 = date1 + span;
- inline
- CComDATE operator+(const CComDATE& date1, const CComSpan& span)
- {
- CComDATE date2;
-
- if( date1.IsValid() && span.IsValid() )
- {
- // Compute the actual date difference by adding underlying data
- date2 = MakeDATE(DATEAsDouble(static_cast<DATE>(date1)) + static_cast<double>(span));
- }
-
- return date2;
- }
-
- // date2 = span + date1;
- inline
- CComDATE operator+(const CComSpan& span, const CComDATE& date1)
- {
- CComDATE date2;
-
- if( date1.IsValid() && span.IsValid() )
- {
- // Compute the actual date difference by adding underlying data
- date2 = MakeDATE(DATEAsDouble(static_cast<DATE>(date1)) + static_cast<double>(span));
- }
-
- return date2;
- }
-
- // date2 = date1 - span;
- inline
- CComDATE operator-(const CComDATE& date1, const CComSpan& span)
- {
- CComDATE date2;
-
- if( date1.IsValid() && span.IsValid() )
- {
- // Compute the actual date difference by adding underlying data
- date2 = MakeDATE(DATEAsDouble(static_cast<DATE>(date1)) - static_cast<double>(span));
- }
-
- return date2;
- }
-
- // span = date1 - date2;
- inline
- CComSpan operator-(const CComDATE& date1, const CComDATE& date2)
- {
- CComSpan span;
-
- if( date1.IsValid() && date2.IsValid() )
- {
- span = DATEAsDouble(static_cast<DATE>(date1)) - DATEAsDouble(static_cast<DATE>(date2));
- }
-
- return span;
- }
-
- // span3 = span1 + span2;
- inline
- CComSpan operator+(const CComSpan& span1, const CComSpan& span2)
- {
- CComSpan span3;
- if( span1.IsValid() && span2.IsValid() ) span3 = span1.m_span + span2.m_span;
- return span3;
- }
-
- // span3 = span1 - span2;
- inline
- CComSpan operator-(const CComSpan& span1, const CComSpan& span2)
- {
- return span1 + (-span2);
- }
-
- #undef HALF_SECOND
- #endif // __COMDATE_H__