1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <sal/config.h>
22 #include "saltime.hxx"
30 #include <mach/clock.h>
31 #include <mach/mach.h>
34 /* FIXME: detection should be done in configure script */
35 #if defined(MACOSX) || defined(IOS) || defined(FREEBSD) || defined(NETBSD) || \
36 defined(LINUX) || defined(OPENBSD) || defined(DRAGONFLY)
37 #define STRUCT_TM_HAS_GMTOFF 1
44 typedef mach_timespec_t osl_time_t
;
46 #if defined(_POSIX_TIMERS)
47 #define USE_CLOCK_GETTIME
48 typedef struct timespec osl_time_t
;
50 typedef struct timeval osl_time_t
;
53 static osl_time_t startTime
;
55 sal_Bool SAL_CALL
osl_getSystemTime(TimeValue
* tv
)
61 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK
, &cclock
);
62 clock_get_time(cclock
, &mts
);
63 mach_port_deallocate(mach_task_self(), cclock
);
65 tv
->Seconds
= mts
.tv_sec
;
66 tv
->Nanosec
= mts
.tv_nsec
;
70 #if defined(USE_CLOCK_GETTIME)
71 res
= clock_gettime(CLOCK_REALTIME
, &tp
);
73 res
= gettimeofday(&tp
, NULL
);
81 tv
->Seconds
= tp
.tv_sec
;
82 #if defined(USE_CLOCK_GETTIME)
83 tv
->Nanosec
= tp
.tv_nsec
;
85 tv
->Nanosec
= tp
.tv_usec
* 1000;
91 sal_Bool SAL_CALL
osl_getDateTimeFromTimeValue( const TimeValue
* pTimeVal
, oslDateTime
* pDateTime
)
93 struct tm
*pSystemTime
;
97 atime
= static_cast<time_t>(pTimeVal
->Seconds
);
99 /* Convert time from type time_t to struct tm */
100 pSystemTime
= gmtime_r( &atime
, &tmBuf
);
102 /* Convert struct tm to struct oslDateTime */
103 if ( pSystemTime
!= nullptr )
105 pDateTime
->NanoSeconds
= pTimeVal
->Nanosec
;
106 pDateTime
->Seconds
= pSystemTime
->tm_sec
;
107 pDateTime
->Minutes
= pSystemTime
->tm_min
;
108 pDateTime
->Hours
= pSystemTime
->tm_hour
;
109 pDateTime
->Day
= pSystemTime
->tm_mday
;
110 pDateTime
->DayOfWeek
= pSystemTime
->tm_wday
;
111 pDateTime
->Month
= pSystemTime
->tm_mon
+ 1;
112 pDateTime
->Year
= pSystemTime
->tm_year
+ 1900;
120 sal_Bool SAL_CALL
osl_getTimeValueFromDateTime( const oslDateTime
* pDateTime
, TimeValue
* pTimeVal
)
125 /* Convert struct oslDateTime to struct tm */
126 aTime
.tm_sec
= pDateTime
->Seconds
;
127 aTime
.tm_min
= pDateTime
->Minutes
;
128 aTime
.tm_hour
= pDateTime
->Hours
;
129 aTime
.tm_mday
= pDateTime
->Day
;
131 if ( pDateTime
->Month
> 0 )
132 aTime
.tm_mon
= pDateTime
->Month
- 1;
136 aTime
.tm_year
= pDateTime
->Year
- 1900;
142 #if defined(STRUCT_TM_HAS_GMTOFF)
146 /* Convert time to calendar value */
147 nSeconds
= mktime( &aTime
);
150 * mktime expects the struct tm to be in local timezone, so we have to adjust
151 * the returned value to be timezone neutral.
154 if ( nSeconds
!= time_t(-1) )
158 /* timezone corrections */
161 #if defined(STRUCT_TM_HAS_GMTOFF)
162 /* members of struct tm are corrected by mktime */
163 bias
= 0 - aTime
.tm_gmtoff
;
165 #elif defined(HAS_ALTZONE)
166 /* check if daylight saving time is in effect */
167 bias
= aTime
.tm_isdst
> 0 ? altzone
: timezone
;
169 /* expect daylight saving time to be one hour */
170 bias
= aTime
.tm_isdst
> 0 ? timezone
- 3600 : timezone
;
173 // coverity[store_truncates_time_t] - TODO: sal_uInt32 TimeValue::Seconds is only large
174 // enough for integer time_t values < 2^32 representing dates until year 2106:
175 pTimeVal
->Seconds
= nSeconds
;
176 pTimeVal
->Nanosec
= pDateTime
->NanoSeconds
;
178 if ( nSeconds
> bias
)
179 pTimeVal
->Seconds
-= bias
;
187 sal_Bool SAL_CALL
osl_getLocalTimeFromSystemTime( const TimeValue
* pSystemTimeVal
, TimeValue
* pLocalTimeVal
)
189 struct tm
*pLocalTime
;
194 atime
= static_cast<time_t>(pSystemTimeVal
->Seconds
);
195 pLocalTime
= localtime_r( &atime
, &tmBuf
);
197 #if defined(STRUCT_TM_HAS_GMTOFF)
198 /* members of struct tm are corrected by mktime */
199 bias
= -pLocalTime
->tm_gmtoff
;
201 #elif defined(HAS_ALTZONE)
202 /* check if daylight saving time is in effect */
203 bias
= pLocalTime
->tm_isdst
> 0 ? altzone
: timezone
;
205 /* expect daylight saving time to be one hour */
206 bias
= pLocalTime
->tm_isdst
> 0 ? timezone
- 3600 : timezone
;
209 if ( static_cast<sal_Int64
>(pSystemTimeVal
->Seconds
) > bias
)
211 pLocalTimeVal
->Seconds
= pSystemTimeVal
->Seconds
- bias
;
212 pLocalTimeVal
->Nanosec
= pSystemTimeVal
->Nanosec
;
220 sal_Bool SAL_CALL
osl_getSystemTimeFromLocalTime( const TimeValue
* pLocalTimeVal
, TimeValue
* pSystemTimeVal
)
222 struct tm
*pLocalTime
;
227 atime
= static_cast<time_t>(pLocalTimeVal
->Seconds
);
229 /* Convert atime, which is a local time, to its GMT equivalent. Then, get
230 * the timezone offset for the local time for the GMT equivalent time. Note
231 * that we cannot directly use local time to determine the timezone offset
232 * because GMT is the only reliable time that we can determine timezone
236 atime
= mktime( gmtime_r( &atime
, &tmBuf
) );
237 pLocalTime
= localtime_r( &atime
, &tmBuf
);
239 #if defined(STRUCT_TM_HAS_GMTOFF)
240 /* members of struct tm are corrected by mktime */
241 bias
= 0 - pLocalTime
->tm_gmtoff
;
243 #elif defined(HAS_ALTZONE)
244 /* check if daylight saving time is in effect */
245 bias
= pLocalTime
->tm_isdst
> 0 ? altzone
: timezone
;
247 /* expect daylight saving time to be one hour */
248 bias
= pLocalTime
->tm_isdst
> 0 ? timezone
- 3600 : timezone
;
251 if ( static_cast<sal_Int64
>(pLocalTimeVal
->Seconds
) + bias
> 0 )
253 pSystemTimeVal
->Seconds
= pLocalTimeVal
->Seconds
+ bias
;
254 pSystemTimeVal
->Nanosec
= pLocalTimeVal
->Nanosec
;
262 void sal_initGlobalTimer()
267 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK
, &cclock
);
268 clock_get_time(cclock
, &startTime
);
269 mach_port_deallocate(mach_task_self(), cclock
);
270 #else /* ! (MACOSX || IOS) */
271 #if defined(USE_CLOCK_GETTIME)
272 clock_gettime(CLOCK_REALTIME
, &startTime
);
273 #else /* Ndef USE_CLOCK_GETTIME */
274 gettimeofday( &startTime
, NULL
);
275 #endif /* NDef USE_CLOCK_GETTIME */
276 #endif /* ! (MACOSX || IOS) */
279 sal_uInt32 SAL_CALL
osl_getGlobalTimer()
285 mach_timespec_t currentTime
;
287 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK
, &cclock
);
288 clock_get_time(cclock
, ¤tTime
);
289 mach_port_deallocate(mach_task_self(), cclock
);
291 nSeconds
= ( currentTime
.tv_sec
- startTime
.tv_sec
);
292 nSeconds
= ( nSeconds
* 1000 ) + static_cast<long>(( currentTime
.tv_nsec
- startTime
.tv_nsec
) / 1000000 );
294 osl_time_t currentTime
;
296 #if defined(USE_CLOCK_GETTIME)
297 clock_gettime(CLOCK_REALTIME
, ¤tTime
);
299 gettimeofday( ¤tTime
, NULL
);
302 nSeconds
= static_cast<sal_uInt32
>( currentTime
.tv_sec
- startTime
.tv_sec
);
303 #if defined(USE_CLOCK_GETTIME)
304 nSeconds
= ( nSeconds
* 1000 ) + static_cast<long>(( currentTime
.tv_nsec
- startTime
.tv_nsec
) / 1000000 );
306 nSeconds
= ( nSeconds
* 1000 ) + (long) (( currentTime
.tv_usec
- startTime
.tv_usec
) / 1000 );
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */