blob: a8ed63b1fb22299a2655171b3e99b1004402c989 [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.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_tools.hxx"
#define _TOOLS_TIME_CXX
#if defined( OS2 )
#define INCL_DOSMISC
#define INCL_DOSDATETIME
#include <svpm.h>
#elif defined( WNT )
#ifdef _MSC_VER
#pragma warning (push,1)
#endif
#include <tools/svwin.h>
#ifdef _MSC_VER
#pragma warning (pop)
#endif
#elif defined UNX
#include <unistd.h>
#include <limits.h>
#include <math.h>
#include <sys/time.h>
#endif
#include <time.h>
#include <tools/time.hxx>
#if defined(SOLARIS) && defined(__GNUC__)
extern long altzone;
#endif
// =======================================================================
static sal_Int32 TimeToSec100( const Time& rTime )
{
short nSign = (rTime.GetTime() >= 0) ? +1 : -1;
sal_Int32 nHour = rTime.GetHour();
sal_Int32 nMin = rTime.GetMin();
sal_Int32 nSec = rTime.GetSec();
sal_Int32 n100Sec = rTime.Get100Sec();
// Wegen Interal Compiler Error bei MSC, etwas komplizierter
// return (n100Sec + (nSec*100) + (nMin*60*100) + (nHour*60*60*100) * nSign);
sal_Int32 nRet = n100Sec;
nRet += nSec*100;
nRet += nMin*60*100;
nRet += nHour*60*60*100;
return (nRet * nSign);
}
// -----------------------------------------------------------------------
static Time Sec100ToTime( sal_Int32 nSec100 )
{
short nSign;
if ( nSec100 < 0 )
{
nSec100 *= -1;
nSign = -1;
}
else
nSign = 1;
Time aTime( 0, 0, 0, nSec100 );
aTime.SetTime( aTime.GetTime() * nSign );
return aTime;
}
// =======================================================================
Time::Time()
{
#if defined( OS2 )
PM_DATETIME aDateTime;
DosGetDateTime( &aDateTime );
// Zeit zusammenbauen
nTime = (((sal_Int32)aDateTime.hours)*1000000) +
(((sal_Int32)aDateTime.minutes)*10000) +
(((sal_Int32)aDateTime.seconds)*100) +
((sal_Int32)aDateTime.hundredths);
#elif defined( WNT )
SYSTEMTIME aDateTime;
GetLocalTime( &aDateTime );
// Zeit zusammenbauen
nTime = (((sal_Int32)aDateTime.wHour)*1000000) +
(((sal_Int32)aDateTime.wMinute)*10000) +
(((sal_Int32)aDateTime.wSecond)*100) +
((sal_Int32)aDateTime.wMilliseconds/10);
#else
time_t nTmpTime;
struct tm aTime;
// Zeit ermitteln
nTmpTime = time( 0 );
// Zeit zusammenbauen
if ( localtime_r( &nTmpTime, &aTime ) )
{
nTime = (((sal_Int32)aTime.tm_hour)*1000000) +
(((sal_Int32)aTime.tm_min)*10000) +
(((sal_Int32)aTime.tm_sec)*100);
}
else
nTime = 0;
#endif
}
// -----------------------------------------------------------------------
Time::Time( const Time& rTime )
{
nTime = rTime.nTime;
}
// -----------------------------------------------------------------------
Time::Time( sal_uIntPtr nHour, sal_uIntPtr nMin, sal_uIntPtr nSec, sal_uIntPtr n100Sec )
{
// Zeit normalisieren
nSec += n100Sec / 100;
n100Sec = n100Sec % 100;
nMin += nSec / 60;
nSec = nSec % 60;
nHour += nMin / 60;
nMin = nMin % 60;
// Zeit zusammenbauen
nTime = (sal_Int32)(n100Sec + (nSec*100) + (nMin*10000) + (nHour*1000000));
}
// -----------------------------------------------------------------------
void Time::SetHour( sal_uInt16 nNewHour )
{
short nSign = (nTime >= 0) ? +1 : -1;
sal_Int32 nMin = GetMin();
sal_Int32 nSec = GetSec();
sal_Int32 n100Sec = Get100Sec();
nTime = (n100Sec + (nSec*100) + (nMin*10000) +
(((sal_Int32)nNewHour)*1000000)) * nSign;
}
// -----------------------------------------------------------------------
void Time::SetMin( sal_uInt16 nNewMin )
{
short nSign = (nTime >= 0) ? +1 : -1;
sal_Int32 nHour = GetHour();
sal_Int32 nSec = GetSec();
sal_Int32 n100Sec = Get100Sec();
// kein Ueberlauf
nNewMin = nNewMin % 60;
nTime = (n100Sec + (nSec*100) + (((sal_Int32)nNewMin)*10000) +
(nHour*1000000)) * nSign;
}
// -----------------------------------------------------------------------
void Time::SetSec( sal_uInt16 nNewSec )
{
short nSign = (nTime >= 0) ? +1 : -1;
sal_Int32 nHour = GetHour();
sal_Int32 nMin = GetMin();
sal_Int32 n100Sec = Get100Sec();
// kein Ueberlauf
nNewSec = nNewSec % 60;
nTime = (n100Sec + (((sal_Int32)nNewSec)*100) + (nMin*10000) +
(nHour*1000000)) * nSign;
}
// -----------------------------------------------------------------------
void Time::Set100Sec( sal_uInt16 nNew100Sec )
{
short nSign = (nTime >= 0) ? +1 : -1;
sal_Int32 nHour = GetHour();
sal_Int32 nMin = GetMin();
sal_Int32 nSec = GetSec();
// kein Ueberlauf
nNew100Sec = nNew100Sec % 100;
nTime = (((sal_Int32)nNew100Sec) + (nSec*100) + (nMin*10000) +
(nHour*1000000)) * nSign;
}
// -----------------------------------------------------------------------
sal_Int32 Time::GetMSFromTime() const
{
short nSign = (nTime >= 0) ? +1 : -1;
sal_Int32 nHour = GetHour();
sal_Int32 nMin = GetMin();
sal_Int32 nSec = GetSec();
sal_Int32 n100Sec = Get100Sec();
return (((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10))*nSign);
}
// -----------------------------------------------------------------------
void Time::MakeTimeFromMS( sal_Int32 nMS )
{
short nSign;
if ( nMS < 0 )
{
nMS *= -1;
nSign = -1;
}
else
nSign = 1;
Time aTime( 0, 0, 0, nMS/10 );
SetTime( aTime.GetTime() * nSign );
}
// -----------------------------------------------------------------------
double Time::GetTimeInDays() const
{
short nSign = (nTime >= 0) ? +1 : -1;
double nHour = GetHour();
double nMin = GetMin();
double nSec = GetSec();
double n100Sec = Get100Sec();
return (nHour+(nMin/60)+(nSec/(60*60))+(n100Sec/(60*60*100))) / 24 * nSign;
}
// -----------------------------------------------------------------------
Time& Time::operator =( const Time& rTime )
{
nTime = rTime.nTime;
return *this;
}
// -----------------------------------------------------------------------
Time& Time::operator +=( const Time& rTime )
{
nTime = Sec100ToTime( TimeToSec100( *this ) +
TimeToSec100( rTime ) ).GetTime();
return *this;
}
// -----------------------------------------------------------------------
Time& Time::operator -=( const Time& rTime )
{
nTime = Sec100ToTime( TimeToSec100( *this ) -
TimeToSec100( rTime ) ).GetTime();
return *this;
}
// -----------------------------------------------------------------------
Time operator +( const Time& rTime1, const Time& rTime2 )
{
return Sec100ToTime( TimeToSec100( rTime1 ) +
TimeToSec100( rTime2 ) );
}
// -----------------------------------------------------------------------
Time operator -( const Time& rTime1, const Time& rTime2 )
{
return Sec100ToTime( TimeToSec100( rTime1 ) -
TimeToSec100( rTime2 ) );
}
// -----------------------------------------------------------------------
sal_Bool Time::IsEqualIgnore100Sec( const Time& rTime ) const
{
sal_Int32 n1 = (nTime < 0 ? -Get100Sec() : Get100Sec() );
sal_Int32 n2 = (rTime.nTime < 0 ? -rTime.Get100Sec() : rTime.Get100Sec() );
return (nTime - n1) == (rTime.nTime - n2);
}
// -----------------------------------------------------------------------
Time Time::GetUTCOffset()
{
#if defined( OS2 )
#undef timezone
PM_DATETIME aDateTime;
DosGetDateTime( &aDateTime );
// Zeit zusammenbauen
if ( aDateTime.timezone != -1 )
{
short nTempTime = (short)Abs( aDateTime.timezone );
Time aTime( 0, (sal_uInt16)nTempTime );
if ( aDateTime.timezone > 0 )
aTime = -aTime;
return aTime;
}
else
return Time( 0 );
#elif defined( WNT )
TIME_ZONE_INFORMATION aTimeZone;
aTimeZone.Bias = 0;
DWORD nTimeZoneRet = GetTimeZoneInformation( &aTimeZone );
sal_Int32 nTempTime = aTimeZone.Bias;
if ( nTimeZoneRet == TIME_ZONE_ID_STANDARD )
nTempTime += aTimeZone.StandardBias;
else if ( nTimeZoneRet == TIME_ZONE_ID_DAYLIGHT )
nTempTime += aTimeZone.DaylightBias;
Time aTime( 0, (sal_uInt16)Abs( nTempTime ) );
if ( nTempTime > 0 )
aTime = -aTime;
return aTime;
#else
static sal_uIntPtr nCacheTicks = 0;
static sal_Int32 nCacheSecOffset = -1;
sal_uIntPtr nTicks = Time::GetSystemTicks();
time_t nTime;
tm aTM;
sal_Int32 nLocalTime;
sal_Int32 nUTC;
short nTempTime;
// Evt. Wert neu ermitteln
if ( (nCacheSecOffset == -1) ||
((nTicks - nCacheTicks) > 360000) ||
( nTicks < nCacheTicks ) // handle overflow
)
{
nTime = time( 0 );
localtime_r( &nTime, &aTM );
nLocalTime = mktime( &aTM );
#if defined( SOLARIS )
// Solaris gmtime_r() seems not to handle daylight saving time
// flags correctly
nUTC = nLocalTime + ( aTM.tm_isdst == 0 ? timezone : altzone );
#elif defined( LINUX )
// Linux mktime() seems not to handle tm_isdst correctly
nUTC = nLocalTime - aTM.tm_gmtoff;
#else
gmtime_r( &nTime, &aTM );
nUTC = mktime( &aTM );
#endif
nCacheTicks = nTicks;
nCacheSecOffset = (nLocalTime-nUTC) / 60;
}
nTempTime = (short)Abs( nCacheSecOffset );
Time aTime( 0, (sal_uInt16)nTempTime );
if ( nCacheSecOffset < 0 )
aTime = -aTime;
return aTime;
#endif
}
// -----------------------------------------------------------------------
sal_uIntPtr Time::GetSystemTicks()
{
#if defined WNT
return (sal_uIntPtr)GetTickCount();
#elif defined( OS2 )
sal_uIntPtr nClock;
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
return (sal_uIntPtr)nClock;
#else
timeval tv;
gettimeofday (&tv, 0);
double fTicks = tv.tv_sec;
fTicks *= 1000;
fTicks += ((tv.tv_usec + 500) / 1000);
fTicks = fmod (fTicks, double(ULONG_MAX));
return sal_uIntPtr(fTicks);
#endif
}
// -----------------------------------------------------------------------
sal_uIntPtr Time::GetProcessTicks()
{
#if defined WNT
return (sal_uIntPtr)GetTickCount();
#elif defined( OS2 )
sal_uIntPtr nClock;
DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, &nClock, sizeof( nClock ) );
return (sal_uIntPtr)nClock;
#else
static sal_uIntPtr nImplTicksPerSecond = 0;
static double dImplTicksPerSecond;
static double dImplTicksULONGMAX;
sal_uIntPtr nTicks = (sal_uIntPtr)clock();
if ( !nImplTicksPerSecond )
{
nImplTicksPerSecond = CLOCKS_PER_SEC;
dImplTicksPerSecond = nImplTicksPerSecond;
dImplTicksULONGMAX = (double)(sal_uIntPtr)ULONG_MAX;
}
double fTicks = nTicks;
fTicks *= 1000;
fTicks /= dImplTicksPerSecond;
fTicks = fmod (fTicks, dImplTicksULONGMAX);
return (sal_uIntPtr)fTicks;
#endif
}