2000-09-18 16:07:07 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2005-09-09 13:11:27 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-09 13:11:27 +00:00
|
|
|
* $RCSfile: ttime.cxx,v $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2006-09-16 23:51:59 +00:00
|
|
|
* $Revision: 1.11 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2006-09-16 23:51:59 +00:00
|
|
|
* last change: $Author: obo $ $Date: 2006-09-17 00:51:59 $
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-09 13:11:27 +00:00
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
|
|
|
*
|
2005-09-09 13:11:27 +00:00
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-09 13:11:27 +00:00
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-09 13:11:27 +00:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
2005-09-09 13:11:27 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
2000-09-18 16:07:07 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-16 23:51:59 +00:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_tools.hxx"
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
#define _TOOLS_TIME_CXX
|
|
|
|
|
2006-06-19 12:37:38 +00:00
|
|
|
#if defined WNT
|
|
|
|
#pragma warning (push,1)
|
2000-09-18 16:07:07 +00:00
|
|
|
#include <svwin.h>
|
2006-06-19 12:37:38 +00:00
|
|
|
#pragma warning (pop)
|
2000-09-18 16:07:07 +00:00
|
|
|
#elif defined UNX
|
|
|
|
#include <unistd.h>
|
2003-03-27 16:05:12 +00:00
|
|
|
#include <limits.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <sys/time.h>
|
2000-09-18 16:07:07 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
#include <time.hxx>
|
|
|
|
|
2005-03-03 16:38:47 +00:00
|
|
|
#if defined(SOLARIS) && defined(__GNUC__)
|
|
|
|
extern long altzone;
|
|
|
|
#endif
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
#ifndef WNT
|
|
|
|
#ifndef localtime_r
|
|
|
|
extern "C" {
|
|
|
|
struct tm *localtime_r(const time_t *timep, struct tm *buffer);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef gmtime_r
|
|
|
|
extern "C" {
|
|
|
|
struct tm *gmtime_r(const time_t *timep, struct tm *buffer);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
static sal_Int32 TimeToSec100( const Time& rTime )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
short nSign = (rTime.GetTime() >= 0) ? +1 : -1;
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 nHour = rTime.GetHour();
|
|
|
|
sal_Int32 nMin = rTime.GetMin();
|
|
|
|
sal_Int32 nSec = rTime.GetSec();
|
|
|
|
sal_Int32 n100Sec = rTime.Get100Sec();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// Wegen Interal Compiler Error bei MSC, etwas komplizierter
|
|
|
|
// return (n100Sec + (nSec*100) + (nMin*60*100) + (nHour*60*60*100) * nSign);
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 nRet = n100Sec;
|
2000-09-18 16:07:07 +00:00
|
|
|
nRet += nSec*100;
|
|
|
|
nRet += nMin*60*100;
|
|
|
|
nRet += nHour*60*60*100;
|
|
|
|
|
|
|
|
return (nRet * nSign);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
static Time Sec100ToTime( sal_Int32 nSec100 )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
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()
|
|
|
|
{
|
2006-06-19 12:37:38 +00:00
|
|
|
#if defined WNT
|
2000-09-18 16:07:07 +00:00
|
|
|
SYSTEMTIME aDateTime;
|
|
|
|
GetLocalTime( &aDateTime );
|
|
|
|
|
|
|
|
// Zeit zusammenbauen
|
2004-06-17 12:11:02 +00:00
|
|
|
nTime = (((sal_Int32)aDateTime.wHour)*1000000) +
|
|
|
|
(((sal_Int32)aDateTime.wMinute)*10000) +
|
|
|
|
(((sal_Int32)aDateTime.wSecond)*100) +
|
|
|
|
((sal_Int32)aDateTime.wMilliseconds/10);
|
2000-09-18 16:07:07 +00:00
|
|
|
#else
|
|
|
|
time_t nTmpTime;
|
|
|
|
struct tm aTime;
|
|
|
|
|
|
|
|
// Zeit ermitteln
|
|
|
|
nTmpTime = time( 0 );
|
|
|
|
|
|
|
|
// Zeit zusammenbauen
|
|
|
|
if ( localtime_r( &nTmpTime, &aTime ) )
|
|
|
|
{
|
2004-06-17 12:11:02 +00:00
|
|
|
nTime = (((sal_Int32)aTime.tm_hour)*1000000) +
|
|
|
|
(((sal_Int32)aTime.tm_min)*10000) +
|
|
|
|
(((sal_Int32)aTime.tm_sec)*100);
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
nTime = 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2003-07-16 16:15:04 +00:00
|
|
|
Time::Time( const Time& rTime )
|
|
|
|
{
|
|
|
|
nTime = rTime.nTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
Time::Time( ULONG nHour, ULONG nMin, ULONG nSec, ULONG n100Sec )
|
|
|
|
{
|
|
|
|
// Zeit normalisieren
|
|
|
|
nSec += n100Sec / 100;
|
|
|
|
n100Sec = n100Sec % 100;
|
|
|
|
nMin += nSec / 60;
|
|
|
|
nSec = nSec % 60;
|
|
|
|
nHour += nMin / 60;
|
|
|
|
nMin = nMin % 60;
|
|
|
|
|
|
|
|
// Zeit zusammenbauen
|
2004-06-17 12:11:02 +00:00
|
|
|
nTime = (sal_Int32)(n100Sec + (nSec*100) + (nMin*10000) + (nHour*1000000));
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Time::SetHour( USHORT nNewHour )
|
|
|
|
{
|
|
|
|
short nSign = (nTime >= 0) ? +1 : -1;
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 nMin = GetMin();
|
|
|
|
sal_Int32 nSec = GetSec();
|
|
|
|
sal_Int32 n100Sec = Get100Sec();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
nTime = (n100Sec + (nSec*100) + (nMin*10000) +
|
2004-06-17 12:11:02 +00:00
|
|
|
(((sal_Int32)nNewHour)*1000000)) * nSign;
|
2000-09-18 16:07:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Time::SetMin( USHORT nNewMin )
|
|
|
|
{
|
|
|
|
short nSign = (nTime >= 0) ? +1 : -1;
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 nHour = GetHour();
|
|
|
|
sal_Int32 nSec = GetSec();
|
|
|
|
sal_Int32 n100Sec = Get100Sec();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// kein Ueberlauf
|
|
|
|
nNewMin = nNewMin % 60;
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
nTime = (n100Sec + (nSec*100) + (((sal_Int32)nNewMin)*10000) +
|
2000-09-18 16:07:07 +00:00
|
|
|
(nHour*1000000)) * nSign;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Time::SetSec( USHORT nNewSec )
|
|
|
|
{
|
2004-06-17 12:11:02 +00:00
|
|
|
short nSign = (nTime >= 0) ? +1 : -1;
|
|
|
|
sal_Int32 nHour = GetHour();
|
|
|
|
sal_Int32 nMin = GetMin();
|
|
|
|
sal_Int32 n100Sec = Get100Sec();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// kein Ueberlauf
|
|
|
|
nNewSec = nNewSec % 60;
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
nTime = (n100Sec + (((sal_Int32)nNewSec)*100) + (nMin*10000) +
|
2000-09-18 16:07:07 +00:00
|
|
|
(nHour*1000000)) * nSign;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Time::Set100Sec( USHORT nNew100Sec )
|
|
|
|
{
|
2004-06-17 12:11:02 +00:00
|
|
|
short nSign = (nTime >= 0) ? +1 : -1;
|
|
|
|
sal_Int32 nHour = GetHour();
|
|
|
|
sal_Int32 nMin = GetMin();
|
|
|
|
sal_Int32 nSec = GetSec();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
// kein Ueberlauf
|
|
|
|
nNew100Sec = nNew100Sec % 100;
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
nTime = (((sal_Int32)nNew100Sec) + (nSec*100) + (nMin*10000) +
|
2000-09-18 16:07:07 +00:00
|
|
|
(nHour*1000000)) * nSign;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 Time::GetMSFromTime() const
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
2004-06-17 12:11:02 +00:00
|
|
|
short nSign = (nTime >= 0) ? +1 : -1;
|
|
|
|
sal_Int32 nHour = GetHour();
|
|
|
|
sal_Int32 nMin = GetMin();
|
|
|
|
sal_Int32 nSec = GetSec();
|
|
|
|
sal_Int32 n100Sec = Get100Sec();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
return (((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10))*nSign);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2004-06-17 12:11:02 +00:00
|
|
|
void Time::MakeTimeFromMS( sal_Int32 nMS )
|
2000-09-18 16:07:07 +00:00
|
|
|
{
|
|
|
|
short nSign;
|
|
|
|
if ( nMS < 0 )
|
|
|
|
{
|
|
|
|
nMS *= -1;
|
|
|
|
nSign = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
nSign = 1;
|
|
|
|
|
|
|
|
Time aTime( 0, 0, 0, nMS/10 );
|
|
|
|
SetTime( aTime.GetTime() * nSign );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
2001-06-11 16:17:46 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
2003-07-16 16:15:04 +00:00
|
|
|
|
|
|
|
Time& Time::operator =( const Time& rTime )
|
|
|
|
{
|
|
|
|
nTime = rTime.nTime;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
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 ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2002-04-15 09:58:58 +00:00
|
|
|
BOOL Time::IsEqualIgnore100Sec( const Time& rTime ) const
|
|
|
|
{
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 n1 = (nTime < 0 ? -Get100Sec() : Get100Sec() );
|
|
|
|
sal_Int32 n2 = (rTime.nTime < 0 ? -rTime.Get100Sec() : rTime.Get100Sec() );
|
2002-04-15 09:58:58 +00:00
|
|
|
return (nTime - n1) == (rTime.nTime - n2);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
Time Time::GetUTCOffset()
|
|
|
|
{
|
2006-06-19 12:37:38 +00:00
|
|
|
#if defined WNT
|
2000-09-18 16:07:07 +00:00
|
|
|
TIME_ZONE_INFORMATION aTimeZone;
|
|
|
|
aTimeZone.Bias = 0;
|
|
|
|
DWORD nTimeZoneRet = GetTimeZoneInformation( &aTimeZone );
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 nTempTime = aTimeZone.Bias;
|
2000-09-18 16:07:07 +00:00
|
|
|
if ( nTimeZoneRet == TIME_ZONE_ID_STANDARD )
|
|
|
|
nTempTime += aTimeZone.StandardBias;
|
|
|
|
else if ( nTimeZoneRet == TIME_ZONE_ID_DAYLIGHT )
|
|
|
|
nTempTime += aTimeZone.DaylightBias;
|
|
|
|
Time aTime( 0, (USHORT)Abs( nTempTime ) );
|
|
|
|
if ( nTempTime > 0 )
|
|
|
|
aTime = -aTime;
|
|
|
|
return aTime;
|
|
|
|
#else
|
|
|
|
static ULONG nCacheTicks = 0;
|
2004-06-17 12:11:02 +00:00
|
|
|
static sal_Int32 nCacheSecOffset = -1;
|
2000-09-18 16:07:07 +00:00
|
|
|
ULONG nTicks = Time::GetSystemTicks();
|
|
|
|
time_t nTime;
|
|
|
|
tm aTM;
|
2004-06-17 12:11:02 +00:00
|
|
|
sal_Int32 nLocalTime;
|
|
|
|
sal_Int32 nUTC;
|
2000-09-18 16:07:07 +00:00
|
|
|
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, (USHORT)nTempTime );
|
|
|
|
if ( nCacheSecOffset < 0 )
|
|
|
|
aTime = -aTime;
|
|
|
|
return aTime;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ULONG Time::GetSystemTicks()
|
|
|
|
{
|
2006-06-19 12:37:38 +00:00
|
|
|
#if defined WNT
|
2000-09-18 16:07:07 +00:00
|
|
|
return (ULONG)GetTickCount();
|
|
|
|
#else
|
2003-03-27 16:05:12 +00:00
|
|
|
timeval tv;
|
|
|
|
gettimeofday (&tv, 0);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
double fTicks = tv.tv_sec;
|
2000-09-18 16:07:07 +00:00
|
|
|
fTicks *= 1000;
|
2003-03-27 16:05:12 +00:00
|
|
|
fTicks += ((tv.tv_usec + 500) / 1000);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
fTicks = fmod (fTicks, double(ULONG_MAX));
|
|
|
|
return ULONG(fTicks);
|
2000-09-18 16:07:07 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ULONG Time::GetProcessTicks()
|
|
|
|
{
|
2006-06-19 12:37:38 +00:00
|
|
|
#if defined WNT
|
2000-09-18 16:07:07 +00:00
|
|
|
return (ULONG)GetTickCount();
|
|
|
|
#else
|
|
|
|
static ULONG nImplTicksPerSecond = 0;
|
|
|
|
static double dImplTicksPerSecond;
|
|
|
|
static double dImplTicksULONGMAX;
|
|
|
|
ULONG nTicks = (ULONG)clock();
|
|
|
|
|
|
|
|
if ( !nImplTicksPerSecond )
|
|
|
|
{
|
|
|
|
nImplTicksPerSecond = CLOCKS_PER_SEC;
|
|
|
|
dImplTicksPerSecond = nImplTicksPerSecond;
|
|
|
|
dImplTicksULONGMAX = (double)(ULONG)ULONG_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
double fTicks = nTicks;
|
|
|
|
fTicks *= 1000;
|
|
|
|
fTicks /= dImplTicksPerSecond;
|
|
|
|
fTicks = fmod (fTicks, dImplTicksULONGMAX);
|
|
|
|
return (ULONG)fTicks;
|
|
|
|
#endif
|
|
|
|
}
|