blob: 4898569bc8a783af9d584a69987f54f89964ecd6 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "system.h"
#include <osl/diagnose.h>
#include <osl/time.h>
/* FIXME: detection should be done in configure script */
#if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) || defined(LINUX)
#define STRUCT_TM_HAS_GMTOFF 1
#elif defined(SOLARIS)
#define HAS_ALTZONE 1
#endif
/*--------------------------------------------------
* osl_getSystemTime
*-------------------------------------------------*/
sal_Bool SAL_CALL osl_getSystemTime(TimeValue* TimeValue)
{
struct timeval tp;
/* FIXME: use higher resolution */
gettimeofday(&tp, NULL);
TimeValue->Seconds = tp.tv_sec;
TimeValue->Nanosec = tp.tv_usec * 1000;
return (sal_True);
}
/*--------------------------------------------------
* osl_getDateTimeFromTimeValue
*-------------------------------------------------*/
sal_Bool SAL_CALL osl_getDateTimeFromTimeValue( TimeValue* pTimeVal, oslDateTime* pDateTime )
{
struct tm *pSystemTime;
struct tm tmBuf;
time_t atime;
atime = (time_t)pTimeVal->Seconds;
/* Convert time from type time_t to struct tm */
pSystemTime = gmtime_r( &atime, &tmBuf );
/* Convert struct tm to struct oslDateTime */
if ( pSystemTime != NULL )
{
pDateTime->NanoSeconds = pTimeVal->Nanosec;
pDateTime->Seconds = pSystemTime->tm_sec;
pDateTime->Minutes = pSystemTime->tm_min;
pDateTime->Hours = pSystemTime->tm_hour;
pDateTime->Day = pSystemTime->tm_mday;
pDateTime->DayOfWeek = pSystemTime->tm_wday;
pDateTime->Month = pSystemTime->tm_mon + 1;
pDateTime->Year = pSystemTime->tm_year + 1900;
return sal_True;
}
return sal_False;
}
/*--------------------------------------------------
* osl_getTimeValueFromDateTime
*--------------------------------------------------*/
sal_Bool SAL_CALL osl_getTimeValueFromDateTime( oslDateTime* pDateTime, TimeValue* pTimeVal )
{
struct tm aTime;
time_t nSeconds;
/* Convert struct oslDateTime to struct tm */
aTime.tm_sec = pDateTime->Seconds;
aTime.tm_min = pDateTime->Minutes;
aTime.tm_hour = pDateTime->Hours;
aTime.tm_mday = pDateTime->Day;
aTime.tm_wday = pDateTime->DayOfWeek;
if ( pDateTime->Month > 0 )
aTime.tm_mon = pDateTime->Month - 1;
else
return sal_False;
if ( pDateTime->Year >= 1900 )
aTime.tm_year = pDateTime->Year - 1900;
else
return sal_False;
aTime.tm_isdst = -1;
aTime.tm_wday = 0;
aTime.tm_yday = 0;
/* Convert time to calendar value */
nSeconds = mktime( &aTime );
/*
* mktime expects the struct tm to be in local timezone, so we have to adjust
* the returned value to be timezone neutral.
*/
if ( nSeconds != (time_t) -1 )
{
time_t bias;
/* timezone corrections */
tzset();
#if defined(STRUCT_TM_HAS_GMTOFF)
/* members of struct tm are corrected by mktime */
bias = 0 - aTime.tm_gmtoff;
#elif defined(HAS_ALTZONE)
/* check if daylight saving time is in effect */
bias = aTime.tm_isdst > 0 ? altzone : timezone;
#else
/* exspect daylight saving time to be one hour */
bias = aTime.tm_isdst > 0 ? timezone - 3600 : timezone;
#endif
pTimeVal->Seconds = nSeconds;
pTimeVal->Nanosec = pDateTime->NanoSeconds;
if ( nSeconds > bias )
pTimeVal->Seconds -= bias;
return sal_True;
}
return sal_False;
}
/*--------------------------------------------------
* osl_getLocalTimeFromSystemTime
*--------------------------------------------------*/
sal_Bool SAL_CALL osl_getLocalTimeFromSystemTime( TimeValue* pSystemTimeVal, TimeValue* pLocalTimeVal )
{
struct tm *pLocalTime;
struct tm tmBuf;
time_t bias;
time_t atime;
atime = (time_t) pSystemTimeVal->Seconds;
pLocalTime = localtime_r( &atime, &tmBuf );
#if defined(STRUCT_TM_HAS_GMTOFF)
/* members of struct tm are corrected by mktime */
bias = 0 - pLocalTime->tm_gmtoff;
#elif defined(HAS_ALTZONE)
/* check if daylight saving time is in effect */
bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
#else
/* exspect daylight saving time to be one hour */
bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
#endif
if ( (sal_Int64) pSystemTimeVal->Seconds > bias )
{
pLocalTimeVal->Seconds = pSystemTimeVal->Seconds - bias;
pLocalTimeVal->Nanosec = pSystemTimeVal->Nanosec;
return sal_True;
}
return sal_False;
}
/*--------------------------------------------------
* osl_getSystemTimeFromLocalTime
*--------------------------------------------------*/
sal_Bool SAL_CALL osl_getSystemTimeFromLocalTime( TimeValue* pLocalTimeVal, TimeValue* pSystemTimeVal )
{
struct tm *pLocalTime;
struct tm tmBuf;
time_t bias;
time_t atime;
atime = (time_t) pLocalTimeVal->Seconds;
/* Convert atime, which is a local time, to it's GMT equivalent. Then, get
* the timezone offset for the local time for the GMT equivalent time. Note
* that we cannot directly use local time to determine the timezone offset
* because GMT is the only reliable time that we can determine timezone
* offset from.
*/
atime = mktime( gmtime_r( &atime, &tmBuf ) );
pLocalTime = localtime_r( &atime, &tmBuf );
#if defined(STRUCT_TM_HAS_GMTOFF)
/* members of struct tm are corrected by mktime */
bias = 0 - pLocalTime->tm_gmtoff;
#elif defined(HAS_ALTZONE)
/* check if daylight saving time is in effect */
bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
#else
/* exspect daylight saving time to be one hour */
bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
#endif
if ( (sal_Int64) pLocalTimeVal->Seconds + bias > 0 )
{
pSystemTimeVal->Seconds = pLocalTimeVal->Seconds + bias;
pSystemTimeVal->Nanosec = pLocalTimeVal->Nanosec;
return sal_True;
}
return sal_False;
}
static struct timeval startTime;
static sal_Bool bGlobalTimer = sal_False;
sal_uInt32 SAL_CALL osl_getGlobalTimer()
{
struct timeval currentTime;
sal_uInt32 nSeconds;
// FIXME: not thread safe !!
if ( bGlobalTimer == sal_False )
{
gettimeofday( &startTime, NULL );
bGlobalTimer=sal_True;
}
gettimeofday( &currentTime, NULL );
nSeconds = (sal_uInt32)( currentTime.tv_sec - startTime.tv_sec );
return ( nSeconds * 1000 ) + (long) (( currentTime.tv_usec - startTime.tv_usec) / 1000 );
}