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
;
130 aTime
.tm_wday
= pDateTime
->DayOfWeek
;
132 if ( pDateTime
->Month
> 0 )
133 aTime
.tm_mon
= pDateTime
->Month
- 1;
137 aTime
.tm_year
= pDateTime
->Year
- 1900;
143 #if defined(STRUCT_TM_HAS_GMTOFF)
147 /* Convert time to calendar value */
148 nSeconds
= mktime( &aTime
);
151 * mktime expects the struct tm to be in local timezone, so we have to adjust
152 * the returned value to be timezone neutral.
155 if ( nSeconds
!= time_t(-1) )
159 /* timezone corrections */
162 #if defined(STRUCT_TM_HAS_GMTOFF)
163 /* members of struct tm are corrected by mktime */
164 bias
= 0 - aTime
.tm_gmtoff
;
166 #elif defined(HAS_ALTZONE)
167 /* check if daylight saving time is in effect */
168 bias
= aTime
.tm_isdst
> 0 ? altzone
: timezone
;
170 /* exspect daylight saving time to be one hour */
171 bias
= aTime
.tm_isdst
> 0 ? timezone
- 3600 : timezone
;
174 pTimeVal
->Seconds
= nSeconds
;
175 pTimeVal
->Nanosec
= pDateTime
->NanoSeconds
;
177 if ( nSeconds
> bias
)
178 pTimeVal
->Seconds
-= bias
;
186 sal_Bool SAL_CALL
osl_getLocalTimeFromSystemTime( const TimeValue
* pSystemTimeVal
, TimeValue
* pLocalTimeVal
)
188 struct tm
*pLocalTime
;
193 atime
= static_cast<time_t>(pSystemTimeVal
->Seconds
);
194 pLocalTime
= localtime_r( &atime
, &tmBuf
);
196 #if defined(STRUCT_TM_HAS_GMTOFF)
197 /* members of struct tm are corrected by mktime */
198 bias
= -pLocalTime
->tm_gmtoff
;
200 #elif defined(HAS_ALTZONE)
201 /* check if daylight saving time is in effect */
202 bias
= pLocalTime
->tm_isdst
> 0 ? altzone
: timezone
;
204 /* expect daylight saving time to be one hour */
205 bias
= pLocalTime
->tm_isdst
> 0 ? timezone
- 3600 : timezone
;
208 if ( static_cast<sal_Int64
>(pSystemTimeVal
->Seconds
) > bias
)
210 pLocalTimeVal
->Seconds
= pSystemTimeVal
->Seconds
- bias
;
211 pLocalTimeVal
->Nanosec
= pSystemTimeVal
->Nanosec
;
219 sal_Bool SAL_CALL
osl_getSystemTimeFromLocalTime( const TimeValue
* pLocalTimeVal
, TimeValue
* pSystemTimeVal
)
221 struct tm
*pLocalTime
;
226 atime
= static_cast<time_t>(pLocalTimeVal
->Seconds
);
228 /* Convert atime, which is a local time, to its GMT equivalent. Then, get
229 * the timezone offset for the local time for the GMT equivalent time. Note
230 * that we cannot directly use local time to determine the timezone offset
231 * because GMT is the only reliable time that we can determine timezone
235 atime
= mktime( gmtime_r( &atime
, &tmBuf
) );
236 pLocalTime
= localtime_r( &atime
, &tmBuf
);
238 #if defined(STRUCT_TM_HAS_GMTOFF)
239 /* members of struct tm are corrected by mktime */
240 bias
= 0 - pLocalTime
->tm_gmtoff
;
242 #elif defined(HAS_ALTZONE)
243 /* check if daylight saving time is in effect */
244 bias
= pLocalTime
->tm_isdst
> 0 ? altzone
: timezone
;
246 /* exspect daylight saving time to be one hour */
247 bias
= pLocalTime
->tm_isdst
> 0 ? timezone
- 3600 : timezone
;
250 if ( static_cast<sal_Int64
>(pLocalTimeVal
->Seconds
) + bias
> 0 )
252 pSystemTimeVal
->Seconds
= pLocalTimeVal
->Seconds
+ bias
;
253 pSystemTimeVal
->Nanosec
= pLocalTimeVal
->Nanosec
;
261 void sal_initGlobalTimer()
266 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK
, &cclock
);
267 clock_get_time(cclock
, &startTime
);
268 mach_port_deallocate(mach_task_self(), cclock
);
269 #else /* ! (MACOSX || IOS) */
270 #if defined(USE_CLOCK_GETTIME)
271 clock_gettime(CLOCK_REALTIME
, &startTime
);
272 #else /* Ndef USE_CLOCK_GETTIME */
273 gettimeofday( &startTime
, NULL
);
274 #endif /* NDef USE_CLOCK_GETTIME */
275 #endif /* ! (MACOSX || IOS) */
278 sal_uInt32 SAL_CALL
osl_getGlobalTimer()
284 mach_timespec_t currentTime
;
286 host_get_clock_service(mach_host_self(), CALENDAR_CLOCK
, &cclock
);
287 clock_get_time(cclock
, ¤tTime
);
288 mach_port_deallocate(mach_task_self(), cclock
);
290 nSeconds
= ( currentTime
.tv_sec
- startTime
.tv_sec
);
291 nSeconds
= ( nSeconds
* 1000 ) + static_cast<long>(( currentTime
.tv_nsec
- startTime
.tv_nsec
) / 1000000 );
293 osl_time_t currentTime
;
295 #if defined(USE_CLOCK_GETTIME)
296 clock_gettime(CLOCK_REALTIME
, ¤tTime
);
298 gettimeofday( ¤tTime
, NULL
);
301 nSeconds
= static_cast<sal_uInt32
>( currentTime
.tv_sec
- startTime
.tv_sec
);
302 #if defined(USE_CLOCK_GETTIME)
303 nSeconds
= ( nSeconds
* 1000 ) + static_cast<long>(( currentTime
.tv_nsec
- startTime
.tv_nsec
) / 1000000 );
305 nSeconds
= ( nSeconds
* 1000 ) + (long) (( currentTime
.tv_usec
- startTime
.tv_usec
) / 1000 );
311 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */