osdTime: win32 use C89 localtime/gmtime
as recommended by Freddie Akeroyd
This commit is contained in:
@@ -121,148 +121,31 @@ static int osdTimeGetCurrent ( epicsTimeStamp *pDest )
|
||||
return epicsTimeOK;
|
||||
}
|
||||
|
||||
inline void UnixTimeToFileTime ( const time_t * pAnsiTime, LPFILETIME pft )
|
||||
{
|
||||
LONGLONG ll = Int32x32To64 ( *pAnsiTime, 10000000 ) + LL_CONSTANT(116444736000000000);
|
||||
pft->dwLowDateTime = static_cast < DWORD > ( ll );
|
||||
pft->dwHighDateTime = static_cast < DWORD > ( ll >>32 );
|
||||
}
|
||||
|
||||
static int daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31,
|
||||
31, 30, 31, 30, 31 };
|
||||
|
||||
static bool isLeapYear ( DWORD year )
|
||||
{
|
||||
if ( (year % 4) == 0 ) {
|
||||
return ( ( year % 100 ) != 0 || ( year % 400 ) == 0 );
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int dayOfYear ( DWORD day, DWORD month, DWORD year )
|
||||
{
|
||||
DWORD nDays = 0;
|
||||
for ( unsigned m = 1; m < month; m++ ) {
|
||||
nDays += daysInMonth[m-1];
|
||||
if ( m == 2 && isLeapYear(year) ) {
|
||||
nDays++;
|
||||
}
|
||||
}
|
||||
return nDays + day;
|
||||
}
|
||||
|
||||
// synthesize a reentrant gmtime on WIN32
|
||||
int epicsShareAPI epicsTime_gmtime ( const time_t *pAnsiTime, struct tm *pTM )
|
||||
{
|
||||
FILETIME ft;
|
||||
UnixTimeToFileTime ( pAnsiTime, &ft );
|
||||
|
||||
SYSTEMTIME st;
|
||||
BOOL status = FileTimeToSystemTime ( &ft, &st );
|
||||
if ( ! status ) {
|
||||
return epicsTimeERROR;
|
||||
struct tm * pRet = gmtime ( pAnsiTime );
|
||||
if ( pRet ) {
|
||||
*pTM = *pRet;
|
||||
return epicsTimeOK;
|
||||
}
|
||||
else {
|
||||
return errno;
|
||||
}
|
||||
|
||||
pTM->tm_sec = st.wSecond; // seconds after the minute - [0,59]
|
||||
pTM->tm_min = st.wMinute; // minutes after the hour - [0,59]
|
||||
pTM->tm_hour = st.wHour; // hours since midnight - [0,23]
|
||||
assert ( st.wDay >= 1 && st.wDay <= 31 );
|
||||
pTM->tm_mday = st.wDay; // day of the month - [1,31]
|
||||
assert ( st.wMonth >= 1 && st.wMonth <= 12 );
|
||||
pTM->tm_mon = st.wMonth - 1; // months since January - [0,11]
|
||||
assert ( st.wYear >= 1900 );
|
||||
pTM->tm_year = st.wYear - 1900; // years since 1900
|
||||
pTM->tm_wday = st.wDayOfWeek; // days since Sunday - [0,6]
|
||||
pTM->tm_yday = dayOfYear ( st.wDay, st.wMonth, st.wYear ) - 1;
|
||||
pTM->tm_isdst = 0;
|
||||
|
||||
return epicsTimeOK;
|
||||
}
|
||||
|
||||
// synthesize a reentrant localtime on WIN32
|
||||
int epicsShareAPI epicsTime_localtime (
|
||||
const time_t * pAnsiTime, struct tm * pTM )
|
||||
{
|
||||
FILETIME ft;
|
||||
UnixTimeToFileTime ( pAnsiTime, & ft );
|
||||
|
||||
TIME_ZONE_INFORMATION tzInfo;
|
||||
DWORD tzStatus = GetTimeZoneInformation ( & tzInfo );
|
||||
if ( tzStatus == TIME_ZONE_ID_INVALID ) {
|
||||
return epicsTimeERROR;
|
||||
struct tm * pRet = localtime ( pAnsiTime );
|
||||
if ( pRet ) {
|
||||
*pTM = *pRet;
|
||||
return epicsTimeOK;
|
||||
}
|
||||
|
||||
//
|
||||
// There are remarkable weaknessess in the FileTimeToLocalFileTime
|
||||
// interface so we dont use it here. Unfortunately, there is no
|
||||
// corresponding function that works on file time.
|
||||
//
|
||||
SYSTEMTIME st;
|
||||
BOOL success = FileTimeToSystemTime ( & ft, & st );
|
||||
if ( ! success ) {
|
||||
return epicsTimeERROR;
|
||||
else {
|
||||
return errno;
|
||||
}
|
||||
SYSTEMTIME lst;
|
||||
success = SystemTimeToTzSpecificLocalTime (
|
||||
& tzInfo, & st, & lst );
|
||||
if ( ! success ) {
|
||||
return epicsTimeERROR;
|
||||
}
|
||||
|
||||
//
|
||||
// We must convert back to file time so that we can determine if DST
|
||||
// is active...
|
||||
//
|
||||
FILETIME lft;
|
||||
success = SystemTimeToFileTime ( & lst, & lft );
|
||||
if ( ! success ) {
|
||||
return epicsTimeERROR;
|
||||
}
|
||||
|
||||
int is_dst = -1; // unknown state of dst
|
||||
if ( tzStatus != TIME_ZONE_ID_UNKNOWN &&
|
||||
tzInfo.StandardDate.wMonth != 0 &&
|
||||
tzInfo.DaylightDate.wMonth != 0) {
|
||||
// determine if the specified date is
|
||||
// in daylight savings time
|
||||
tzInfo.StandardDate.wYear = st.wYear;
|
||||
FILETIME StandardDateFT;
|
||||
success = SystemTimeToFileTime (
|
||||
& tzInfo.StandardDate, & StandardDateFT );
|
||||
if ( ! success ) {
|
||||
return epicsTimeERROR;
|
||||
}
|
||||
tzInfo.DaylightDate.wYear = st.wYear;
|
||||
FILETIME DaylightDateFT;
|
||||
success = SystemTimeToFileTime (
|
||||
& tzInfo.DaylightDate, & DaylightDateFT );
|
||||
if ( ! success ) {
|
||||
return epicsTimeERROR;
|
||||
}
|
||||
if ( CompareFileTime ( & lft, & DaylightDateFT ) >= 0
|
||||
&& CompareFileTime ( & lft, & StandardDateFT ) < 0 ) {
|
||||
is_dst = 1;
|
||||
}
|
||||
else {
|
||||
is_dst = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pTM->tm_sec = lst.wSecond; // seconds after the minute - [0,59]
|
||||
pTM->tm_min = lst.wMinute; // minutes after the hour - [0,59]
|
||||
pTM->tm_hour = lst.wHour; // hours since midnight - [0,23]
|
||||
assert ( lst.wDay >= 1 && lst.wDay <= 31 );
|
||||
pTM->tm_mday = lst.wDay; // day of the month - [1,31]
|
||||
assert ( lst.wMonth >= 1 && lst.wMonth <= 12 );
|
||||
pTM->tm_mon = lst.wMonth - 1; // months since January - [0,11]
|
||||
assert ( lst.wYear >= 1900 );
|
||||
pTM->tm_year = lst.wYear - 1900; // years since 1900
|
||||
pTM->tm_wday = lst.wDayOfWeek; // days since Sunday - [0,6]
|
||||
pTM->tm_yday = dayOfYear ( lst.wDay, lst.wMonth, lst.wYear ) - 1;
|
||||
pTM->tm_isdst = is_dst;
|
||||
|
||||
return epicsTimeOK;
|
||||
}
|
||||
|
||||
currentTime::currentTime () :
|
||||
|
||||
Reference in New Issue
Block a user