Z_Beeblebrox
asked on
Convert time_t to DATE
Hi,
I am using VC++ 6 and I have an ATL service in which I need to convert a time represented as seconds since Jan 1, 1970 into a DATE type for storage in a _variant_t. What is the easiest way to make this conversion?
Thanks,
Zaphod.
I am using VC++ 6 and I have an ATL service in which I need to convert a time represented as seconds since Jan 1, 1970 into a DATE type for storage in a _variant_t. What is the easiest way to make this conversion?
Thanks,
Zaphod.
Try that
DATE time_t_To_DATE(time_t t)
{
COleDateTime cdt( t );
return (DATE)cdt;
}
Regards, Alex
DATE time_t_To_DATE(time_t t)
{
COleDateTime cdt( t );
return (DATE)cdt;
}
Regards, Alex
ASKER
Can I use that code in a non-MFC application? I tried including afxdisp.h but that gave me the error:
#error : WINDOWS.H already included. MFC apps must not #include <windows.h>
Zaphod.
#error : WINDOWS.H already included. MFC apps must not #include <windows.h>
Zaphod.
>> Can I use that code in a non-MFC application?
I wouldn't do that as you would have to link against MFC libraries.
DATE is a double value that has the number of days since December, 30 1899 left of the decimal point and the fractional part is the hour values.
I'll check MFC sources if there is an easy way to convert these data types.
Regards, Alex
I wouldn't do that as you would have to link against MFC libraries.
DATE is a double value that has the number of days since December, 30 1899 left of the decimal point and the fractional part is the hour values.
I'll check MFC sources if there is an easy way to convert these data types.
Regards, Alex
Ok, one step forwards, two backwards ... ;-)
const COleDateTime& COleDateTime::operator=(co nst time_t& timeSrc)
{
// Convert time_t to struct tm
tm *ptm = localtime(&timeSrc);
if (ptm != NULL)
{
m_status = _AfxOleDateFromTm((WORD)(p tm->tm_yea r + 1900),
(WORD)(ptm->tm_mon + 1), (WORD)ptm->tm_mday,
(WORD)ptm->tm_hour, (WORD)ptm->tm_min,
(WORD)ptm->tm_sec, m_dt) ? valid : invalid;
}
else
{
// Local time must have failed (timsSrc before 1/1/70 12am)
SetStatus(invalid);
ASSERT(FALSE);
}
return *this;
}
And that:
AFX_STATIC BOOL AFXAPI _AfxOleDateFromTm(WORD wYear, WORD wMonth, WORD wDay,
WORD wHour, WORD wMinute, WORD wSecond, DATE& dtDest)
{
// Validate year and month (ignore day of week and milliseconds)
if (wYear > 9999 || wMonth < 1 || wMonth > 12)
return FALSE;
// Check for leap year and set the number of days in the month
BOOL bLeapYear = ((wYear & 3) == 0) &&
((wYear % 100) != 0 || (wYear % 400) == 0);
int nDaysInMonth =
_afxMonthDays[wMonth] - _afxMonthDays[wMonth-1] +
((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0);
// Finish validating the date
if (wDay < 1 || wDay > nDaysInMonth ||
wHour > 23 || wMinute > 59 ||
wSecond > 59)
{
return FALSE;
}
// Cache the date in days and time in fractional days
long nDate;
double dblTime;
//It is a valid date; make Jan 1, 1AD be 1
nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 +
_afxMonthDays[wMonth-1] + wDay;
// If leap year and it's before March, subtract 1:
if (wMonth <= 2 && bLeapYear)
--nDate;
// Offset so that 12/30/1899 is 0
nDate -= 693959L;
dblTime = (((long)wHour * 3600L) + // hrs in seconds
((long)wMinute * 60L) + // mins in seconds
((long)wSecond)) / 86400.;
dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime);
return TRUE;
}
Regards, Alex
const COleDateTime& COleDateTime::operator=(co
{
// Convert time_t to struct tm
tm *ptm = localtime(&timeSrc);
if (ptm != NULL)
{
m_status = _AfxOleDateFromTm((WORD)(p
(WORD)(ptm->tm_mon + 1), (WORD)ptm->tm_mday,
(WORD)ptm->tm_hour, (WORD)ptm->tm_min,
(WORD)ptm->tm_sec, m_dt) ? valid : invalid;
}
else
{
// Local time must have failed (timsSrc before 1/1/70 12am)
SetStatus(invalid);
ASSERT(FALSE);
}
return *this;
}
And that:
AFX_STATIC BOOL AFXAPI _AfxOleDateFromTm(WORD wYear, WORD wMonth, WORD wDay,
WORD wHour, WORD wMinute, WORD wSecond, DATE& dtDest)
{
// Validate year and month (ignore day of week and milliseconds)
if (wYear > 9999 || wMonth < 1 || wMonth > 12)
return FALSE;
// Check for leap year and set the number of days in the month
BOOL bLeapYear = ((wYear & 3) == 0) &&
((wYear % 100) != 0 || (wYear % 400) == 0);
int nDaysInMonth =
_afxMonthDays[wMonth] - _afxMonthDays[wMonth-1] +
((bLeapYear && wDay == 29 && wMonth == 2) ? 1 : 0);
// Finish validating the date
if (wDay < 1 || wDay > nDaysInMonth ||
wHour > 23 || wMinute > 59 ||
wSecond > 59)
{
return FALSE;
}
// Cache the date in days and time in fractional days
long nDate;
double dblTime;
//It is a valid date; make Jan 1, 1AD be 1
nDate = wYear*365L + wYear/4 - wYear/100 + wYear/400 +
_afxMonthDays[wMonth-1] + wDay;
// If leap year and it's before March, subtract 1:
if (wMonth <= 2 && bLeapYear)
--nDate;
// Offset so that 12/30/1899 is 0
nDate -= 693959L;
dblTime = (((long)wHour * 3600L) + // hrs in seconds
((long)wMinute * 60L) + // mins in seconds
((long)wSecond)) / 86400.;
dtDest = (double) nDate + ((nDate >= 0) ? dblTime : -dblTime);
return TRUE;
}
Regards, Alex
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Wow, that's quite a bit of code. If there is no built in function to do this (in the absence of MFC) would it not be easier to take the tm structure you obtained at the beginning and then manually populate a SYTEMTIME structure, which can then be passed into the SystemTimeToVariantTime function? This would be quite a bit simpler and easier to read. Of course, this approach didn't occur to me until I saw your code.
Zaphod.
Zaphod.
If it works, it is good.
I assume they use the same code as above - stolen from the same AFX source ;-)
Regards, Alex
I assume they use the same code as above - stolen from the same AFX source ;-)
Regards, Alex
If you know that time_t is valid you could use that function:
DATE time_t_To_DATE(time_t timeSrc)
{
static int monthDays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
// Convert time_t to struct tm
tm* ptm = localtime(&timeSrc);
int year = (ptm->tm_year + 1900);
int month = (ptm->tm_mon + 1);
int day = ptm->tm_mday;
int hour = ptm->tm_hour;
int minute = ptm->tm_min;
int second = ptm->tm_sec;
// Check for leap year and set the number of days in the month
BOOL bLeapYear = ((year & 3) == 0 &&
((year % 100) != 0 || (year % 400) == 0));
int nDaysInMonth = monthDays[month] - monthDays[month-1] +
((bLeapYear && day == 29 && month == 2) ? 1 : 0);
// Cache the date in days and time in fractional days
// Offset so that 12/30/1899 is 0
long nDate= year*365L + year/4 - year/100 + year/400 +
monthDays[month-1] + day - 693959L;
// If leap year and it's before March, subtract 1:
if (month <= 2 && bLeapYear)
--nDate;
return (double) nDate + (((long)hour * 3600L) + // hrs in seconds
((long)minute * 60L) + // mins in seconds
((long)second)) / 86400.;
}
But, the SystemTimeToVariantTime is a very good idea (though not from me).
Regards, Alex
DATE time_t_To_DATE(time_t timeSrc)
{
static int monthDays[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
// Convert time_t to struct tm
tm* ptm = localtime(&timeSrc);
int year = (ptm->tm_year + 1900);
int month = (ptm->tm_mon + 1);
int day = ptm->tm_mday;
int hour = ptm->tm_hour;
int minute = ptm->tm_min;
int second = ptm->tm_sec;
// Check for leap year and set the number of days in the month
BOOL bLeapYear = ((year & 3) == 0 &&
((year % 100) != 0 || (year % 400) == 0));
int nDaysInMonth = monthDays[month] - monthDays[month-1] +
((bLeapYear && day == 29 && month == 2) ? 1 : 0);
// Cache the date in days and time in fractional days
// Offset so that 12/30/1899 is 0
long nDate= year*365L + year/4 - year/100 + year/400 +
monthDays[month-1] + day - 693959L;
// If leap year and it's before March, subtract 1:
if (month <= 2 && bLeapYear)
--nDate;
return (double) nDate + (((long)hour * 3600L) + // hrs in seconds
((long)minute * 60L) + // mins in seconds
((long)second)) / 86400.;
}
But, the SystemTimeToVariantTime is a very good idea (though not from me).
Regards, Alex
ASKER
Zaphod.