1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ttime.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_tools.hxx"
34 #define _TOOLS_TIME_CXX
38 #define INCL_DOSDATETIME
42 #pragma warning (push,1)
44 #include <tools/svwin.h>
56 #include <tools/time.hxx>
58 #if defined(SOLARIS) && defined(__GNUC__)
62 // =======================================================================
64 static sal_Int32
TimeToSec100( const Time
& rTime
)
66 short nSign
= (rTime
.GetTime() >= 0) ? +1 : -1;
67 sal_Int32 nHour
= rTime
.GetHour();
68 sal_Int32 nMin
= rTime
.GetMin();
69 sal_Int32 nSec
= rTime
.GetSec();
70 sal_Int32 n100Sec
= rTime
.Get100Sec();
72 // Wegen Interal Compiler Error bei MSC, etwas komplizierter
73 // return (n100Sec + (nSec*100) + (nMin*60*100) + (nHour*60*60*100) * nSign);
75 sal_Int32 nRet
= n100Sec
;
78 nRet
+= nHour
*60*60*100;
80 return (nRet
* nSign
);
83 // -----------------------------------------------------------------------
85 static Time
Sec100ToTime( sal_Int32 nSec100
)
96 Time
aTime( 0, 0, 0, nSec100
);
97 aTime
.SetTime( aTime
.GetTime() * nSign
);
101 // =======================================================================
107 DosGetDateTime( &aDateTime
);
109 // Zeit zusammenbauen
110 nTime
= (((sal_Int32
)aDateTime
.hours
)*1000000) +
111 (((sal_Int32
)aDateTime
.minutes
)*10000) +
112 (((sal_Int32
)aDateTime
.seconds
)*100) +
113 ((sal_Int32
)aDateTime
.hundredths
);
115 SYSTEMTIME aDateTime
;
116 GetLocalTime( &aDateTime
);
118 // Zeit zusammenbauen
119 nTime
= (((sal_Int32
)aDateTime
.wHour
)*1000000) +
120 (((sal_Int32
)aDateTime
.wMinute
)*10000) +
121 (((sal_Int32
)aDateTime
.wSecond
)*100) +
122 ((sal_Int32
)aDateTime
.wMilliseconds
/10);
128 nTmpTime
= time( 0 );
130 // Zeit zusammenbauen
131 if ( localtime_r( &nTmpTime
, &aTime
) )
133 nTime
= (((sal_Int32
)aTime
.tm_hour
)*1000000) +
134 (((sal_Int32
)aTime
.tm_min
)*10000) +
135 (((sal_Int32
)aTime
.tm_sec
)*100);
142 // -----------------------------------------------------------------------
144 Time::Time( const Time
& rTime
)
149 // -----------------------------------------------------------------------
151 Time::Time( ULONG nHour
, ULONG nMin
, ULONG nSec
, ULONG n100Sec
)
153 // Zeit normalisieren
154 nSec
+= n100Sec
/ 100;
155 n100Sec
= n100Sec
% 100;
161 // Zeit zusammenbauen
162 nTime
= (sal_Int32
)(n100Sec
+ (nSec
*100) + (nMin
*10000) + (nHour
*1000000));
165 // -----------------------------------------------------------------------
167 void Time::SetHour( USHORT nNewHour
)
169 short nSign
= (nTime
>= 0) ? +1 : -1;
170 sal_Int32 nMin
= GetMin();
171 sal_Int32 nSec
= GetSec();
172 sal_Int32 n100Sec
= Get100Sec();
174 nTime
= (n100Sec
+ (nSec
*100) + (nMin
*10000) +
175 (((sal_Int32
)nNewHour
)*1000000)) * nSign
;
178 // -----------------------------------------------------------------------
180 void Time::SetMin( USHORT nNewMin
)
182 short nSign
= (nTime
>= 0) ? +1 : -1;
183 sal_Int32 nHour
= GetHour();
184 sal_Int32 nSec
= GetSec();
185 sal_Int32 n100Sec
= Get100Sec();
188 nNewMin
= nNewMin
% 60;
190 nTime
= (n100Sec
+ (nSec
*100) + (((sal_Int32
)nNewMin
)*10000) +
191 (nHour
*1000000)) * nSign
;
194 // -----------------------------------------------------------------------
196 void Time::SetSec( USHORT nNewSec
)
198 short nSign
= (nTime
>= 0) ? +1 : -1;
199 sal_Int32 nHour
= GetHour();
200 sal_Int32 nMin
= GetMin();
201 sal_Int32 n100Sec
= Get100Sec();
204 nNewSec
= nNewSec
% 60;
206 nTime
= (n100Sec
+ (((sal_Int32
)nNewSec
)*100) + (nMin
*10000) +
207 (nHour
*1000000)) * nSign
;
210 // -----------------------------------------------------------------------
212 void Time::Set100Sec( USHORT nNew100Sec
)
214 short nSign
= (nTime
>= 0) ? +1 : -1;
215 sal_Int32 nHour
= GetHour();
216 sal_Int32 nMin
= GetMin();
217 sal_Int32 nSec
= GetSec();
220 nNew100Sec
= nNew100Sec
% 100;
222 nTime
= (((sal_Int32
)nNew100Sec
) + (nSec
*100) + (nMin
*10000) +
223 (nHour
*1000000)) * nSign
;
226 // -----------------------------------------------------------------------
228 sal_Int32
Time::GetMSFromTime() const
230 short nSign
= (nTime
>= 0) ? +1 : -1;
231 sal_Int32 nHour
= GetHour();
232 sal_Int32 nMin
= GetMin();
233 sal_Int32 nSec
= GetSec();
234 sal_Int32 n100Sec
= Get100Sec();
236 return (((nHour
*3600000)+(nMin
*60000)+(nSec
*1000)+(n100Sec
*10))*nSign
);
239 // -----------------------------------------------------------------------
241 void Time::MakeTimeFromMS( sal_Int32 nMS
)
252 Time
aTime( 0, 0, 0, nMS
/10 );
253 SetTime( aTime
.GetTime() * nSign
);
256 // -----------------------------------------------------------------------
258 double Time::GetTimeInDays() const
260 short nSign
= (nTime
>= 0) ? +1 : -1;
261 double nHour
= GetHour();
262 double nMin
= GetMin();
263 double nSec
= GetSec();
264 double n100Sec
= Get100Sec();
266 return (nHour
+(nMin
/60)+(nSec
/(60*60))+(n100Sec
/(60*60*100))) / 24 * nSign
;
269 // -----------------------------------------------------------------------
271 Time
& Time::operator =( const Time
& rTime
)
277 // -----------------------------------------------------------------------
279 Time
& Time::operator +=( const Time
& rTime
)
281 nTime
= Sec100ToTime( TimeToSec100( *this ) +
282 TimeToSec100( rTime
) ).GetTime();
286 // -----------------------------------------------------------------------
288 Time
& Time::operator -=( const Time
& rTime
)
290 nTime
= Sec100ToTime( TimeToSec100( *this ) -
291 TimeToSec100( rTime
) ).GetTime();
295 // -----------------------------------------------------------------------
297 Time
operator +( const Time
& rTime1
, const Time
& rTime2
)
299 return Sec100ToTime( TimeToSec100( rTime1
) +
300 TimeToSec100( rTime2
) );
303 // -----------------------------------------------------------------------
305 Time
operator -( const Time
& rTime1
, const Time
& rTime2
)
307 return Sec100ToTime( TimeToSec100( rTime1
) -
308 TimeToSec100( rTime2
) );
311 // -----------------------------------------------------------------------
313 BOOL
Time::IsEqualIgnore100Sec( const Time
& rTime
) const
315 sal_Int32 n1
= (nTime
< 0 ? -Get100Sec() : Get100Sec() );
316 sal_Int32 n2
= (rTime
.nTime
< 0 ? -rTime
.Get100Sec() : rTime
.Get100Sec() );
317 return (nTime
- n1
) == (rTime
.nTime
- n2
);
320 // -----------------------------------------------------------------------
322 Time
Time::GetUTCOffset()
327 DosGetDateTime( &aDateTime
);
329 // Zeit zusammenbauen
330 if ( aDateTime
.timezone
!= -1 )
332 short nTempTime
= (short)Abs( aDateTime
.timezone
);
333 Time
aTime( 0, (USHORT
)nTempTime
);
334 if ( aDateTime
.timezone
> 0 )
341 TIME_ZONE_INFORMATION aTimeZone
;
343 DWORD nTimeZoneRet
= GetTimeZoneInformation( &aTimeZone
);
344 sal_Int32 nTempTime
= aTimeZone
.Bias
;
345 if ( nTimeZoneRet
== TIME_ZONE_ID_STANDARD
)
346 nTempTime
+= aTimeZone
.StandardBias
;
347 else if ( nTimeZoneRet
== TIME_ZONE_ID_DAYLIGHT
)
348 nTempTime
+= aTimeZone
.DaylightBias
;
349 Time
aTime( 0, (USHORT
)Abs( nTempTime
) );
354 static ULONG nCacheTicks
= 0;
355 static sal_Int32 nCacheSecOffset
= -1;
356 ULONG nTicks
= Time::GetSystemTicks();
359 sal_Int32 nLocalTime
;
363 // Evt. Wert neu ermitteln
364 if ( (nCacheSecOffset
== -1) ||
365 ((nTicks
- nCacheTicks
) > 360000) ||
366 ( nTicks
< nCacheTicks
) // handle overflow
370 localtime_r( &nTime
, &aTM
);
371 nLocalTime
= mktime( &aTM
);
372 #if defined( SOLARIS )
373 // Solaris gmtime_r() seems not to handle daylight saving time
375 nUTC
= nLocalTime
+ ( aTM
.tm_isdst
== 0 ? timezone
: altzone
);
376 #elif defined( LINUX )
377 // Linux mktime() seems not to handle tm_isdst correctly
378 nUTC
= nLocalTime
- aTM
.tm_gmtoff
;
380 gmtime_r( &nTime
, &aTM
);
381 nUTC
= mktime( &aTM
);
383 nCacheTicks
= nTicks
;
384 nCacheSecOffset
= (nLocalTime
-nUTC
) / 60;
387 nTempTime
= (short)Abs( nCacheSecOffset
);
388 Time
aTime( 0, (USHORT
)nTempTime
);
389 if ( nCacheSecOffset
< 0 )
396 // -----------------------------------------------------------------------
398 ULONG
Time::GetSystemTicks()
401 return (ULONG
)GetTickCount();
404 DosQuerySysInfo( QSV_MS_COUNT
, QSV_MS_COUNT
, &nClock
, sizeof( nClock
) );
405 return (ULONG
)nClock
;
408 gettimeofday (&tv
, 0);
410 double fTicks
= tv
.tv_sec
;
412 fTicks
+= ((tv
.tv_usec
+ 500) / 1000);
414 fTicks
= fmod (fTicks
, double(ULONG_MAX
));
415 return ULONG(fTicks
);
419 // -----------------------------------------------------------------------
421 ULONG
Time::GetProcessTicks()
424 return (ULONG
)GetTickCount();
427 DosQuerySysInfo( QSV_MS_COUNT
, QSV_MS_COUNT
, &nClock
, sizeof( nClock
) );
428 return (ULONG
)nClock
;
430 static ULONG nImplTicksPerSecond
= 0;
431 static double dImplTicksPerSecond
;
432 static double dImplTicksULONGMAX
;
433 ULONG nTicks
= (ULONG
)clock();
435 if ( !nImplTicksPerSecond
)
437 nImplTicksPerSecond
= CLOCKS_PER_SEC
;
438 dImplTicksPerSecond
= nImplTicksPerSecond
;
439 dImplTicksULONGMAX
= (double)(ULONG
)ULONG_MAX
;
442 double fTicks
= nTicks
;
444 fTicks
/= dImplTicksPerSecond
;
445 fTicks
= fmod (fTicks
, dImplTicksULONGMAX
);
446 return (ULONG
)fTicks
;