Branch data 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 : : #include <tools/time.hxx>
31 : :
32 : : #if defined(SOLARIS) && defined(__GNUC__)
33 : : extern long altzone;
34 : : #endif
35 : :
36 : 1090 : static sal_Int32 TimeToSec100( const Time& rTime )
37 : : {
38 [ + + ]: 1090 : short nSign = (rTime.GetTime() >= 0) ? +1 : -1;
39 : 1090 : sal_Int32 nHour = rTime.GetHour();
40 : 1090 : sal_Int32 nMin = rTime.GetMin();
41 : 1090 : sal_Int32 nSec = rTime.GetSec();
42 : 1090 : sal_Int32 n100Sec = rTime.Get100Sec();
43 : :
44 : : // Due to interal compiler error in MSC a little bit more complicated:
45 : : // return (n100Sec + (nSec*100) + (nMin*60*100) + (nHour*60*60*100) * nSign);
46 : :
47 : 1090 : sal_Int32 nRet = n100Sec;
48 : 1090 : nRet += nSec*100;
49 : 1090 : nRet += nMin*60*100;
50 : 1090 : nRet += nHour*60*60*100;
51 : :
52 : 1090 : return (nRet * nSign);
53 : : }
54 : :
55 : 545 : static Time Sec100ToTime( sal_Int32 nSec100 )
56 : : {
57 : : short nSign;
58 [ - + ]: 545 : if ( nSec100 < 0 )
59 : : {
60 : 0 : nSec100 *= -1;
61 : 0 : nSign = -1;
62 : : }
63 : : else
64 : 545 : nSign = 1;
65 : :
66 : 545 : Time aTime( 0, 0, 0, nSec100 );
67 : 545 : aTime.SetTime( aTime.GetTime() * nSign );
68 : 545 : return aTime;
69 : : }
70 : :
71 : 18090 : Time::Time( TimeInitSystem )
72 : : {
73 : : #if defined( WNT )
74 : : SYSTEMTIME aDateTime;
75 : : GetLocalTime( &aDateTime );
76 : :
77 : : // construct time
78 : : nTime = (((sal_Int32)aDateTime.wHour)*1000000) +
79 : : (((sal_Int32)aDateTime.wMinute)*10000) +
80 : : (((sal_Int32)aDateTime.wSecond)*100) +
81 : : ((sal_Int32)aDateTime.wMilliseconds/10);
82 : : #else
83 : : time_t nTmpTime;
84 : : struct tm aTime;
85 : :
86 : : // determine time
87 : 18090 : nTmpTime = time( 0 );
88 : :
89 : : // construct time
90 [ + - ]: 18090 : if ( localtime_r( &nTmpTime, &aTime ) )
91 : : {
92 : : nTime = (((sal_Int32)aTime.tm_hour)*1000000) +
93 : : (((sal_Int32)aTime.tm_min)*10000) +
94 : 18090 : (((sal_Int32)aTime.tm_sec)*100);
95 : : }
96 : : else
97 : 0 : nTime = 0;
98 : : #endif
99 : 18090 : }
100 : :
101 : 9936 : Time::Time( const Time& rTime )
102 : : {
103 : 9936 : nTime = rTime.nTime;
104 : 9936 : }
105 : :
106 : 33007 : Time::Time( sal_uIntPtr nHour, sal_uIntPtr nMin, sal_uIntPtr nSec, sal_uIntPtr n100Sec )
107 : : {
108 : : // normalize time
109 : 33007 : nSec += n100Sec / 100;
110 : 33007 : n100Sec = n100Sec % 100;
111 : 33007 : nMin += nSec / 60;
112 : 33007 : nSec = nSec % 60;
113 : 33007 : nHour += nMin / 60;
114 : 33007 : nMin = nMin % 60;
115 : :
116 : : // construct time
117 : 33007 : nTime = (sal_Int32)(n100Sec + (nSec*100) + (nMin*10000) + (nHour*1000000));
118 : 33007 : }
119 : :
120 : 573 : void Time::SetHour( sal_uInt16 nNewHour )
121 : : {
122 [ + - ]: 573 : short nSign = (nTime >= 0) ? +1 : -1;
123 : 573 : sal_Int32 nMin = GetMin();
124 : 573 : sal_Int32 nSec = GetSec();
125 : 573 : sal_Int32 n100Sec = Get100Sec();
126 : :
127 : : nTime = (n100Sec + (nSec*100) + (nMin*10000) +
128 : 573 : (((sal_Int32)nNewHour)*1000000)) * nSign;
129 : 573 : }
130 : :
131 : 40 : void Time::SetMin( sal_uInt16 nNewMin )
132 : : {
133 [ + - ]: 40 : short nSign = (nTime >= 0) ? +1 : -1;
134 : 40 : sal_Int32 nHour = GetHour();
135 : 40 : sal_Int32 nSec = GetSec();
136 : 40 : sal_Int32 n100Sec = Get100Sec();
137 : :
138 : : // no overflow
139 : 40 : nNewMin = nNewMin % 60;
140 : :
141 : : nTime = (n100Sec + (nSec*100) + (((sal_Int32)nNewMin)*10000) +
142 : 40 : (nHour*1000000)) * nSign;
143 : 40 : }
144 : :
145 : 3927 : void Time::SetSec( sal_uInt16 nNewSec )
146 : : {
147 [ + - ]: 3927 : short nSign = (nTime >= 0) ? +1 : -1;
148 : 3927 : sal_Int32 nHour = GetHour();
149 : 3927 : sal_Int32 nMin = GetMin();
150 : 3927 : sal_Int32 n100Sec = Get100Sec();
151 : :
152 : : // no overflow
153 : 3927 : nNewSec = nNewSec % 60;
154 : :
155 : : nTime = (n100Sec + (((sal_Int32)nNewSec)*100) + (nMin*10000) +
156 : 3927 : (nHour*1000000)) * nSign;
157 : 3927 : }
158 : :
159 : 3887 : void Time::Set100Sec( sal_uInt16 nNew100Sec )
160 : : {
161 [ + - ]: 3887 : short nSign = (nTime >= 0) ? +1 : -1;
162 : 3887 : sal_Int32 nHour = GetHour();
163 : 3887 : sal_Int32 nMin = GetMin();
164 : 3887 : sal_Int32 nSec = GetSec();
165 : :
166 : : // no overflow
167 : 3887 : nNew100Sec = nNew100Sec % 100;
168 : :
169 : : nTime = (((sal_Int32)nNew100Sec) + (nSec*100) + (nMin*10000) +
170 : 3887 : (nHour*1000000)) * nSign;
171 : 3887 : }
172 : :
173 : 2138 : sal_Int32 Time::GetMSFromTime() const
174 : : {
175 [ + - ]: 2138 : short nSign = (nTime >= 0) ? +1 : -1;
176 : 2138 : sal_Int32 nHour = GetHour();
177 : 2138 : sal_Int32 nMin = GetMin();
178 : 2138 : sal_Int32 nSec = GetSec();
179 : 2138 : sal_Int32 n100Sec = Get100Sec();
180 : :
181 : 2138 : return (((nHour*3600000)+(nMin*60000)+(nSec*1000)+(n100Sec*10))*nSign);
182 : : }
183 : :
184 : 0 : void Time::MakeTimeFromMS( sal_Int32 nMS )
185 : : {
186 : : short nSign;
187 [ # # ]: 0 : if ( nMS < 0 )
188 : : {
189 : 0 : nMS *= -1;
190 : 0 : nSign = -1;
191 : : }
192 : : else
193 : 0 : nSign = 1;
194 : :
195 [ # # ]: 0 : Time aTime( 0, 0, 0, nMS/10 );
196 : 0 : SetTime( aTime.GetTime() * nSign );
197 : 0 : }
198 : :
199 : 0 : double Time::GetTimeInDays() const
200 : : {
201 [ # # ]: 0 : short nSign = (nTime >= 0) ? +1 : -1;
202 : 0 : double nHour = GetHour();
203 : 0 : double nMin = GetMin();
204 : 0 : double nSec = GetSec();
205 : 0 : double n100Sec = Get100Sec();
206 : :
207 : 0 : return (nHour+(nMin/60)+(nSec/(60*60))+(n100Sec/(60*60*100))) / 24 * nSign;
208 : : }
209 : :
210 : 111087 : Time& Time::operator =( const Time& rTime )
211 : : {
212 : 111087 : nTime = rTime.nTime;
213 : 111087 : return *this;
214 : : }
215 : :
216 : 510 : Time& Time::operator +=( const Time& rTime )
217 : : {
218 : 510 : nTime = Sec100ToTime( TimeToSec100( *this ) +
219 : 510 : TimeToSec100( rTime ) ).GetTime();
220 : 510 : return *this;
221 : : }
222 : :
223 : 35 : Time& Time::operator -=( const Time& rTime )
224 : : {
225 : 35 : nTime = Sec100ToTime( TimeToSec100( *this ) -
226 : 35 : TimeToSec100( rTime ) ).GetTime();
227 : 35 : return *this;
228 : : }
229 : :
230 : 0 : Time operator +( const Time& rTime1, const Time& rTime2 )
231 : : {
232 : 0 : return Sec100ToTime( TimeToSec100( rTime1 ) +
233 : 0 : TimeToSec100( rTime2 ) );
234 : : }
235 : :
236 : 0 : Time operator -( const Time& rTime1, const Time& rTime2 )
237 : : {
238 : 0 : return Sec100ToTime( TimeToSec100( rTime1 ) -
239 : 0 : TimeToSec100( rTime2 ) );
240 : : }
241 : :
242 : 0 : sal_Bool Time::IsEqualIgnore100Sec( const Time& rTime ) const
243 : : {
244 [ # # ]: 0 : sal_Int32 n1 = (nTime < 0 ? -Get100Sec() : Get100Sec() );
245 [ # # ]: 0 : sal_Int32 n2 = (rTime.nTime < 0 ? -rTime.Get100Sec() : rTime.Get100Sec() );
246 : 0 : return (nTime - n1) == (rTime.nTime - n2);
247 : : }
248 : :
249 : 533 : Time Time::GetUTCOffset()
250 : : {
251 : : #if defined( WNT )
252 : : TIME_ZONE_INFORMATION aTimeZone;
253 : : aTimeZone.Bias = 0;
254 : : DWORD nTimeZoneRet = GetTimeZoneInformation( &aTimeZone );
255 : : sal_Int32 nTempTime = aTimeZone.Bias;
256 : : if ( nTimeZoneRet == TIME_ZONE_ID_STANDARD )
257 : : nTempTime += aTimeZone.StandardBias;
258 : : else if ( nTimeZoneRet == TIME_ZONE_ID_DAYLIGHT )
259 : : nTempTime += aTimeZone.DaylightBias;
260 : : Time aTime( 0, (sal_uInt16)Abs( nTempTime ) );
261 : : if ( nTempTime > 0 )
262 : : aTime = -aTime;
263 : : return aTime;
264 : : #else
265 : : static sal_uIntPtr nCacheTicks = 0;
266 : : static sal_Int32 nCacheSecOffset = -1;
267 [ + - ]: 533 : sal_uIntPtr nTicks = Time::GetSystemTicks();
268 : : time_t nTime;
269 : : tm aTM;
270 : : sal_Int32 nLocalTime;
271 : : sal_Int32 nUTC;
272 : : short nTempTime;
273 : :
274 : : // determine value again if needed
275 [ + + ][ + - ]: 533 : if ( (nCacheSecOffset == -1) ||
[ - + ]
276 : : ((nTicks - nCacheTicks) > 360000) ||
277 : : ( nTicks < nCacheTicks ) // handle overflow
278 : : )
279 : : {
280 : 37 : nTime = time( 0 );
281 : 37 : localtime_r( &nTime, &aTM );
282 : 37 : nLocalTime = mktime( &aTM );
283 : : #if defined( SOLARIS )
284 : : // Solaris gmtime_r() seems not to handle daylight saving time
285 : : // flags correctly
286 : : nUTC = nLocalTime + ( aTM.tm_isdst == 0 ? timezone : altzone );
287 : : #elif defined( LINUX )
288 : : // Linux mktime() seems not to handle tm_isdst correctly
289 : 37 : nUTC = nLocalTime - aTM.tm_gmtoff;
290 : : #else
291 : : gmtime_r( &nTime, &aTM );
292 : : nUTC = mktime( &aTM );
293 : : #endif
294 : 37 : nCacheTicks = nTicks;
295 : 37 : nCacheSecOffset = (nLocalTime-nUTC) / 60;
296 : : }
297 : :
298 : 533 : nTempTime = (short)Abs( nCacheSecOffset );
299 [ + - ]: 533 : Time aTime( 0, (sal_uInt16)nTempTime );
300 [ - + ]: 533 : if ( nCacheSecOffset < 0 )
301 [ # # ]: 533 : aTime = -aTime;
302 : 533 : return aTime;
303 : : #endif
304 : : }
305 : :
306 : 824140 : sal_uIntPtr Time::GetSystemTicks()
307 : : {
308 : : #if defined WNT
309 : : return (sal_uIntPtr)GetTickCount();
310 : : #else
311 : : timeval tv;
312 : 824140 : gettimeofday (&tv, 0);
313 : :
314 : 824140 : double fTicks = tv.tv_sec;
315 : 824140 : fTicks *= 1000;
316 : 824140 : fTicks += ((tv.tv_usec + 500) / 1000);
317 : :
318 : 824140 : fTicks = fmod (fTicks, double(ULONG_MAX));
319 : 824140 : return sal_uIntPtr(fTicks);
320 : : #endif
321 : : }
322 : :
323 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|