LCOV - code coverage report
Current view: top level - tools/source/datetime - ttime.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 140 188 74.5 %
Date: 2014-04-11 Functions: 18 24 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #if defined( WNT )
      21             : #include <windows.h>
      22             : #elif defined UNX
      23             : #include <unistd.h>
      24             : #include <limits.h>
      25             : #include <math.h>
      26             : #include <sys/time.h>
      27             : #endif
      28             : 
      29             : #include <time.h>
      30             : #ifdef __MACH__
      31             : #include <mach/clock.h>
      32             : #include <mach/mach.h>
      33             : #endif
      34             : #include <tools/time.hxx>
      35             : 
      36             : #include <osl/diagnose.h>
      37             : 
      38             : #if defined(SOLARIS) && defined(__GNUC__)
      39             : extern long altzone;
      40             : #endif
      41             : 
      42             : namespace {
      43             : 
      44             :     const sal_Int64 secMask  = SAL_CONST_INT64(1000000000);
      45             :     const sal_Int64 minMask  = SAL_CONST_INT64(100000000000);
      46             :     const sal_Int64 hourMask = SAL_CONST_INT64(10000000000000);
      47             : 
      48             :     const sal_Int64 nanoSecInSec = 1000000000;
      49             :     const sal_Int16 secInMin     = 60;
      50             :     const sal_Int16 minInHour    = 60;
      51             : 
      52         686 :     sal_Int64 TimeToNanoSec( const Time& rTime )
      53             :     {
      54         686 :         short  nSign   = (rTime.GetTime() >= 0) ? +1 : -1;
      55         686 :         sal_Int32   nHour    = rTime.GetHour();
      56         686 :         sal_Int32   nMin     = rTime.GetMin();
      57         686 :         sal_Int32   nSec     = rTime.GetSec();
      58         686 :         sal_Int32   nNanoSec = rTime.GetNanoSec();
      59             : 
      60         686 :         sal_Int64 nRet = nNanoSec;
      61         686 :         nRet     +=            nSec * nanoSecInSec;
      62         686 :         nRet     +=       nMin * secInMin * nanoSecInSec;
      63         686 :         nRet     += nHour * minInHour * secInMin * nanoSecInSec;
      64             : 
      65         686 :         return (nRet * nSign);
      66             :     }
      67             : 
      68         343 :     Time NanoSecToTime( sal_Int64 nNanoSec )
      69             :     {
      70             :         short nSign;
      71         343 :         if ( nNanoSec < 0 )
      72             :         {
      73           0 :             nNanoSec *= -1;
      74           0 :             nSign = -1;
      75             :         }
      76             :         else
      77         343 :             nSign = 1;
      78             : 
      79         343 :         Time aTime( 0, 0, 0, nNanoSec );
      80         343 :         aTime.SetTime( aTime.GetTime() * nSign );
      81         343 :         return aTime;
      82             :     }
      83             : 
      84             : } // anonymous namespace
      85             : 
      86        9401 : Time::Time( TimeInitSystem )
      87             : {
      88             : #if defined( WNT )
      89             :     SYSTEMTIME aDateTime;
      90             :     GetLocalTime( &aDateTime );
      91             : 
      92             :     // construct time
      93             :     nTime = aDateTime.wHour         * hourMask +
      94             :             aDateTime.wMinute       * minMask +
      95             :             aDateTime.wSecond       * secMask +
      96             :             aDateTime.wMilliseconds * 1000000;
      97             : #else
      98             :     // determine time
      99             :     struct timespec tsTime;
     100             : #if defined( __MACH__ )
     101             :     // OS X does not have clock_gettime, use clock_get_time
     102             :     clock_serv_t cclock;
     103             :     mach_timespec_t mts;
     104             :     host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
     105             :     clock_get_time(cclock, &mts);
     106             :     mach_port_deallocate(mach_task_self(), cclock);
     107             :     tsTime.tv_sec  = mts.tv_sec;
     108             :     tsTime.tv_nsec = mts.tv_nsec;
     109             : #else
     110             :     // CLOCK_REALTIME should be supported
     111             :     // on any modern Unix, but be extra cautious
     112        9401 :     if (clock_gettime(CLOCK_REALTIME, &tsTime) != 0)
     113             :     {
     114             :         struct timeval tvTime;
     115           0 :         OSL_VERIFY( gettimeofday(&tvTime, NULL) != 0 );
     116           0 :         tsTime.tv_sec  = tvTime.tv_sec;
     117           0 :         tsTime.tv_nsec = tvTime.tv_usec * 1000;
     118             :     }
     119             : #endif // __MACH__
     120             : 
     121             :     // construct time
     122             :     struct tm aTime;
     123        9401 :     time_t nTmpTime = tsTime.tv_sec;
     124        9401 :     if ( localtime_r( &nTmpTime, &aTime ) )
     125             :     {
     126       18802 :         nTime = aTime.tm_hour * hourMask +
     127       18802 :                 aTime.tm_min  * minMask +
     128       18802 :                 aTime.tm_sec  * secMask +
     129        9401 :                 tsTime.tv_nsec;
     130             :     }
     131             :     else
     132           0 :         nTime = 0;
     133             : #endif // WNT
     134        9401 : }
     135             : 
     136       10333 : Time::Time( const Time& rTime )
     137             : {
     138       10333 :     nTime = rTime.nTime;
     139       10333 : }
     140             : 
     141        3735 : Time::Time( sal_uInt32 nHour, sal_uInt32 nMin, sal_uInt32 nSec, sal_uInt64 nNanoSec )
     142             : {
     143        3735 :     init(nHour, nMin, nSec, nNanoSec);
     144        3735 : }
     145         105 : Time::Time( const ::com::sun::star::util::Time &_rTime )
     146             : {
     147         105 :     init(_rTime.Hours, _rTime.Minutes, _rTime.Seconds, _rTime.NanoSeconds);
     148         105 : }
     149        3840 : void Time::init( sal_uInt32 nHour, sal_uInt32 nMin, sal_uInt32 nSec, sal_uInt64 nNanoSec )
     150             : {
     151             :     // normalize time
     152        3840 :     nSec     += nNanoSec / nanoSecInSec;
     153        3840 :     nNanoSec %= nanoSecInSec;
     154        3840 :     nMin     += nSec / secInMin;
     155        3840 :     nSec     %= secInMin;
     156        3840 :     nHour    += nMin / minInHour;
     157        3840 :     nMin     %= minInHour;
     158             : 
     159             :     // construct time
     160             :     nTime = nNanoSec +
     161        7680 :             nSec  * secMask +
     162        7680 :             nMin  * minMask +
     163        7680 :             nHour * hourMask;
     164        3840 : }
     165             : 
     166         356 : void Time::SetHour( sal_uInt16 nNewHour )
     167             : {
     168         356 :     short  nSign          = (nTime >= 0) ? +1 : -1;
     169         356 :     sal_Int32   nMin      = GetMin();
     170         356 :     sal_Int32   nSec      = GetSec();
     171         356 :     sal_Int32   nNanoSec  = GetNanoSec();
     172             : 
     173         712 :     nTime = nSign *
     174         712 :             ( nNanoSec +
     175         712 :               nSec  * secMask +
     176         712 :               nMin  * minMask +
     177         712 :               nNewHour * hourMask );
     178         356 : }
     179             : 
     180          34 : void Time::SetMin( sal_uInt16 nNewMin )
     181             : {
     182          34 :     short  nSign          = (nTime >= 0) ? +1 : -1;
     183          34 :     sal_Int32   nHour     = GetHour();
     184          34 :     sal_Int32   nSec      = GetSec();
     185          34 :     sal_Int32   nNanoSec  = GetNanoSec();
     186             : 
     187             :     // no overflow
     188          34 :     nNewMin = nNewMin % minInHour;
     189             : 
     190          68 :     nTime = nSign *
     191          68 :             ( nNanoSec +
     192          68 :               nSec  * secMask +
     193          68 :               nNewMin  * minMask +
     194          68 :               nHour * hourMask );
     195          34 : }
     196             : 
     197        1617 : void Time::SetSec( sal_uInt16 nNewSec )
     198             : {
     199        1617 :     short       nSign     = (nTime >= 0) ? +1 : -1;
     200        1617 :     sal_Int32   nHour     = GetHour();
     201        1617 :     sal_Int32   nMin      = GetMin();
     202        1617 :     sal_Int32   nNanoSec   = GetNanoSec();
     203             : 
     204             :     // no overflow
     205        1617 :     nNewSec = nNewSec % secInMin;
     206             : 
     207        3234 :     nTime = nSign *
     208        3234 :             ( nNanoSec +
     209        3234 :               nNewSec  * secMask +
     210        3234 :               nMin  * minMask +
     211        3234 :               nHour * hourMask );
     212        1617 : }
     213             : 
     214        1586 : void Time::SetNanoSec( sal_uInt32 nNewNanoSec )
     215             : {
     216        1586 :     short       nSign     = (nTime >= 0) ? +1 : -1;
     217        1586 :     sal_Int32   nHour     = GetHour();
     218        1586 :     sal_Int32   nMin      = GetMin();
     219        1586 :     sal_Int32   nSec      = GetSec();
     220             : 
     221             :     // no overflow
     222        1586 :     nNewNanoSec = nNewNanoSec % nanoSecInSec;
     223             : 
     224        3172 :     nTime = nSign *
     225        3172 :             ( nNewNanoSec +
     226        3172 :               nSec  * secMask +
     227        3172 :               nMin  * minMask +
     228        3172 :               nHour * hourMask );
     229        1586 : }
     230             : 
     231        3298 : sal_Int64 Time::GetNSFromTime() const
     232             : {
     233        3298 :     short       nSign     = (nTime >= 0) ? +1 : -1;
     234        3298 :     sal_Int32   nHour     = GetHour();
     235        3298 :     sal_Int32   nMin      = GetMin();
     236        3298 :     sal_Int32   nSec      = GetSec();
     237        3298 :     sal_Int32   nNanoSec  = GetNanoSec();
     238             : 
     239        3298 :     return nSign *
     240        6596 :            ( nNanoSec +
     241        6596 :              nSec  * nanoSecInSec +
     242        6596 :              nMin  * (secInMin * nanoSecInSec) +
     243        6596 :              nHour * (minInHour * secInMin * nanoSecInSec) );
     244             : }
     245             : 
     246           0 : void Time::MakeTimeFromNS( sal_Int64 nNS )
     247             : {
     248             :     short nSign;
     249           0 :     if ( nNS < 0 )
     250             :     {
     251           0 :         nNS *= -1;
     252           0 :         nSign = -1;
     253             :     }
     254             :     else
     255           0 :         nSign = 1;
     256             : 
     257             :     // avoid overflow when sal_uIntPtr is 32 bits
     258           0 :     Time aTime( 0, 0, nNS/nanoSecInSec, nNS % nanoSecInSec );
     259           0 :     SetTime( aTime.GetTime() * nSign );
     260           0 : }
     261             : 
     262           0 : sal_Int32 Time::GetMSFromTime() const
     263             : {
     264           0 :     short       nSign     = (nTime >= 0) ? +1 : -1;
     265           0 :     sal_Int32   nHour     = GetHour();
     266           0 :     sal_Int32   nMin      = GetMin();
     267           0 :     sal_Int32   nSec      = GetSec();
     268           0 :     sal_Int32   nNanoSec  = GetNanoSec();
     269             : 
     270           0 :     return nSign *
     271           0 :            ( nNanoSec/1000000 +
     272           0 :              nSec  * 1000 +
     273           0 :              nMin  * 60000 +
     274           0 :              nHour * 360000 );
     275             : }
     276             : 
     277           0 : void Time::MakeTimeFromMS( sal_Int32 nMS )
     278             : {
     279             :     short nSign;
     280           0 :     if ( nMS < 0 )
     281             :     {
     282           0 :         nMS *= -1;
     283           0 :         nSign = -1;
     284             :     }
     285             :     else
     286           0 :         nSign = 1;
     287             : 
     288             :     // avoid overflow when sal_uIntPtr is 32 bits
     289           0 :     Time aTime( 0, 0, nMS/1000, (nMS % 1000) * 1000000 );
     290           0 :     SetTime( aTime.GetTime() * nSign );
     291           0 : }
     292             : 
     293           0 : double Time::GetTimeInDays() const
     294             : {
     295           0 :     short  nSign      = (nTime >= 0) ? +1 : -1;
     296           0 :     double nHour      = GetHour();
     297           0 :     double nMin       = GetMin();
     298           0 :     double nSec       = GetSec();
     299           0 :     double nNanoSec   = GetNanoSec();
     300             : 
     301           0 :     return (nHour + (nMin / 60) + (nSec / (minInHour * secInMin)) + (nNanoSec / (minInHour * secInMin * nanoSecInSec))) / 24 * nSign;
     302             : }
     303             : 
     304        5011 : Time& Time::operator =( const Time& rTime )
     305             : {
     306        5011 :     nTime = rTime.nTime;
     307        5011 :     return *this;
     308             : }
     309             : 
     310         286 : Time& Time::operator +=( const Time& rTime )
     311             : {
     312         286 :     nTime = NanoSecToTime( TimeToNanoSec( *this ) +
     313         286 :                            TimeToNanoSec( rTime ) ).GetTime();
     314         286 :     return *this;
     315             : }
     316             : 
     317          42 : Time& Time::operator -=( const Time& rTime )
     318             : {
     319          42 :     nTime = NanoSecToTime( TimeToNanoSec( *this ) -
     320          42 :                            TimeToNanoSec( rTime ) ).GetTime();
     321          42 :     return *this;
     322             : }
     323             : 
     324           0 : Time operator +( const Time& rTime1, const Time& rTime2 )
     325             : {
     326           0 :     return NanoSecToTime( TimeToNanoSec( rTime1 ) +
     327           0 :                           TimeToNanoSec( rTime2 ) );
     328             : }
     329             : 
     330          15 : Time operator -( const Time& rTime1, const Time& rTime2 )
     331             : {
     332          15 :     return NanoSecToTime( TimeToNanoSec( rTime1 ) -
     333          15 :                           TimeToNanoSec( rTime2 ) );
     334             : }
     335             : 
     336           0 : bool Time::IsEqualIgnoreNanoSec( const Time& rTime ) const
     337             : {
     338           0 :     sal_Int32 n1 = (nTime       < 0 ? -static_cast<sal_Int32>(GetNanoSec())       : GetNanoSec() );
     339           0 :     sal_Int32 n2 = (rTime.nTime < 0 ? -static_cast<sal_Int32>(rTime.GetNanoSec()) : rTime.GetNanoSec() );
     340           0 :     return (nTime - n1) == (rTime.nTime - n2);
     341             : }
     342             : 
     343         319 : Time Time::GetUTCOffset()
     344             : {
     345             : #if defined( WNT )
     346             :     TIME_ZONE_INFORMATION   aTimeZone;
     347             :     aTimeZone.Bias = 0;
     348             :     DWORD nTimeZoneRet = GetTimeZoneInformation( &aTimeZone );
     349             :     sal_Int32 nTempTime = aTimeZone.Bias;
     350             :     if ( nTimeZoneRet == TIME_ZONE_ID_STANDARD )
     351             :         nTempTime += aTimeZone.StandardBias;
     352             :     else if ( nTimeZoneRet == TIME_ZONE_ID_DAYLIGHT )
     353             :         nTempTime += aTimeZone.DaylightBias;
     354             :     Time aTime( 0, (sal_uInt16)abs( nTempTime ) );
     355             :     if ( nTempTime > 0 )
     356             :         aTime = -aTime;
     357             :     return aTime;
     358             : #else
     359             :     static sal_uIntPtr  nCacheTicks = 0;
     360             :     static sal_Int32    nCacheSecOffset = -1;
     361         319 :     sal_uIntPtr         nTicks = Time::GetSystemTicks();
     362             :     time_t          nTime;
     363             :     tm              aTM;
     364             :     sal_Int32           nLocalTime;
     365             :     sal_Int32           nUTC;
     366             :     short           nTempTime;
     367             : 
     368             :     // determine value again if needed
     369         625 :     if ( (nCacheSecOffset == -1)            ||
     370         612 :          ((nTicks - nCacheTicks) > 360000)  ||
     371         306 :          ( nTicks < nCacheTicks ) // handle overflow
     372             :          )
     373             :     {
     374          13 :         nTime = time( 0 );
     375          13 :         localtime_r( &nTime, &aTM );
     376          13 :         nLocalTime = mktime( &aTM );
     377             : #if defined( SOLARIS )
     378             :         // Solaris gmtime_r() seems not to handle daylight saving time
     379             :         // flags correctly
     380             :         nUTC = nLocalTime + ( aTM.tm_isdst == 0 ? timezone : altzone );
     381             : #elif defined( LINUX )
     382             :         // Linux mktime() seems not to handle tm_isdst correctly
     383          13 :         nUTC = nLocalTime - aTM.tm_gmtoff;
     384             : #else
     385             :          gmtime_r( &nTime, &aTM );
     386             :          nUTC = mktime( &aTM );
     387             : #endif
     388          13 :          nCacheTicks = nTicks;
     389          13 :          nCacheSecOffset = (nLocalTime-nUTC) / 60;
     390             :     }
     391             : 
     392         319 :     nTempTime = abs( nCacheSecOffset );
     393         319 :     Time aTime( 0, (sal_uInt16)nTempTime );
     394         319 :     if ( nCacheSecOffset < 0 )
     395           0 :         aTime = -aTime;
     396         319 :     return aTime;
     397             : #endif
     398             : }
     399             : 
     400      586429 : sal_uIntPtr Time::GetSystemTicks()
     401             : {
     402             : #if defined WNT
     403             :     return (sal_uIntPtr)GetTickCount();
     404             : #else
     405             :     timeval tv;
     406      586429 :     gettimeofday (&tv, 0);
     407             : 
     408      586429 :     double fTicks = tv.tv_sec;
     409      586429 :     fTicks *= 1000;
     410      586429 :     fTicks += ((tv.tv_usec + 500) / 1000);
     411             : 
     412      586429 :     fTicks = fmod (fTicks, double(ULONG_MAX));
     413      586429 :     return sal_uIntPtr(fTicks);
     414             : #endif
     415             : }
     416             : 
     417             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10