bump product version to 4.1.6.2
[LibreOffice.git] / sal / osl / unx / time.c
blob971a63a9e757fa06cd7a091e766b2fc2b481c4fc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include "system.h"
23 #include <osl/diagnose.h>
24 #include <osl/time.h>
25 #include <time.h>
27 /* FIXME: detection should be done in configure script */
28 #if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) || \
29 defined(LINUX) || defined(OPENBSD) || defined(DRAGONFLY)
30 #define STRUCT_TM_HAS_GMTOFF 1
32 #elif defined(SOLARIS)
33 #define HAS_ALTZONE 1
34 #endif
36 /*--------------------------------------------------
37 * osl_getSystemTime
38 *-------------------------------------------------*/
40 sal_Bool SAL_CALL osl_getSystemTime(TimeValue* tv)
42 int res;
43 #if defined(LINUX)
44 struct timespec tp;
46 res = clock_gettime(CLOCK_REALTIME, &tp);
47 #else
48 struct timeval tp;
50 res = gettimeofday(&tp, NULL);
51 #endif
53 if (res != 0)
55 return sal_False;
58 tv->Seconds = tp.tv_sec;
59 #if defined(LINUX)
60 tv->Nanosec = tp.tv_nsec;
61 #else
62 tv->Nanosec = tp.tv_usec * 1000;
63 #endif
65 return sal_True;
69 /*--------------------------------------------------
70 * osl_getDateTimeFromTimeValue
71 *-------------------------------------------------*/
73 sal_Bool SAL_CALL osl_getDateTimeFromTimeValue( const TimeValue* pTimeVal, oslDateTime* pDateTime )
75 struct tm *pSystemTime;
76 struct tm tmBuf;
77 time_t atime;
79 atime = (time_t)pTimeVal->Seconds;
81 /* Convert time from type time_t to struct tm */
82 pSystemTime = gmtime_r( &atime, &tmBuf );
85 /* Convert struct tm to struct oslDateTime */
86 if ( pSystemTime != NULL )
88 pDateTime->NanoSeconds = pTimeVal->Nanosec;
89 pDateTime->Seconds = pSystemTime->tm_sec;
90 pDateTime->Minutes = pSystemTime->tm_min;
91 pDateTime->Hours = pSystemTime->tm_hour;
92 pDateTime->Day = pSystemTime->tm_mday;
93 pDateTime->DayOfWeek = pSystemTime->tm_wday;
94 pDateTime->Month = pSystemTime->tm_mon + 1;
95 pDateTime->Year = pSystemTime->tm_year + 1900;
97 return sal_True;
100 return sal_False;
103 /*--------------------------------------------------
104 * osl_getTimeValueFromDateTime
105 *--------------------------------------------------*/
107 sal_Bool SAL_CALL osl_getTimeValueFromDateTime( const oslDateTime* pDateTime, TimeValue* pTimeVal )
109 struct tm aTime;
110 time_t nSeconds;
112 /* Convert struct oslDateTime to struct tm */
113 aTime.tm_sec = pDateTime->Seconds;
114 aTime.tm_min = pDateTime->Minutes;
115 aTime.tm_hour = pDateTime->Hours;
116 aTime.tm_mday = pDateTime->Day;
117 aTime.tm_wday = pDateTime->DayOfWeek;
119 if ( pDateTime->Month > 0 )
120 aTime.tm_mon = pDateTime->Month - 1;
121 else
122 return sal_False;
124 if ( pDateTime->Year >= 1900 )
125 aTime.tm_year = pDateTime->Year - 1900;
126 else
127 return sal_False;
129 aTime.tm_isdst = -1;
130 aTime.tm_wday = 0;
131 aTime.tm_yday = 0;
133 /* Convert time to calendar value */
134 nSeconds = mktime( &aTime );
137 * mktime expects the struct tm to be in local timezone, so we have to adjust
138 * the returned value to be timezone neutral.
141 if ( nSeconds != (time_t) -1 )
143 time_t bias;
145 /* timezone corrections */
146 tzset();
148 #if defined(STRUCT_TM_HAS_GMTOFF)
149 /* members of struct tm are corrected by mktime */
150 bias = 0 - aTime.tm_gmtoff;
152 #elif defined(HAS_ALTZONE)
153 /* check if daylight saving time is in effect */
154 bias = aTime.tm_isdst > 0 ? altzone : timezone;
155 #else
156 /* exspect daylight saving time to be one hour */
157 bias = aTime.tm_isdst > 0 ? timezone - 3600 : timezone;
158 #endif
160 pTimeVal->Seconds = nSeconds;
161 pTimeVal->Nanosec = pDateTime->NanoSeconds;
163 if ( nSeconds > bias )
164 pTimeVal->Seconds -= bias;
166 return sal_True;
169 return sal_False;
173 /*--------------------------------------------------
174 * osl_getLocalTimeFromSystemTime
175 *--------------------------------------------------*/
177 sal_Bool SAL_CALL osl_getLocalTimeFromSystemTime( const TimeValue* pSystemTimeVal, TimeValue* pLocalTimeVal )
179 struct tm *pLocalTime;
180 struct tm tmBuf;
181 time_t bias;
182 time_t atime;
184 atime = (time_t) pSystemTimeVal->Seconds;
185 pLocalTime = localtime_r( &atime, &tmBuf );
187 #if defined(STRUCT_TM_HAS_GMTOFF)
188 /* members of struct tm are corrected by mktime */
189 bias = 0 - pLocalTime->tm_gmtoff;
191 #elif defined(HAS_ALTZONE)
192 /* check if daylight saving time is in effect */
193 bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
194 #else
195 /* exspect daylight saving time to be one hour */
196 bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
197 #endif
199 if ( (sal_Int64) pSystemTimeVal->Seconds > bias )
201 pLocalTimeVal->Seconds = pSystemTimeVal->Seconds - bias;
202 pLocalTimeVal->Nanosec = pSystemTimeVal->Nanosec;
204 return sal_True;
207 return sal_False;
210 /*--------------------------------------------------
211 * osl_getSystemTimeFromLocalTime
212 *--------------------------------------------------*/
214 sal_Bool SAL_CALL osl_getSystemTimeFromLocalTime( const TimeValue* pLocalTimeVal, TimeValue* pSystemTimeVal )
216 struct tm *pLocalTime;
217 struct tm tmBuf;
218 time_t bias;
219 time_t atime;
221 atime = (time_t) pLocalTimeVal->Seconds;
223 /* Convert atime, which is a local time, to it's GMT equivalent. Then, get
224 * the timezone offset for the local time for the GMT equivalent time. Note
225 * that we cannot directly use local time to determine the timezone offset
226 * because GMT is the only reliable time that we can determine timezone
227 * offset from.
230 atime = mktime( gmtime_r( &atime, &tmBuf ) );
231 pLocalTime = localtime_r( &atime, &tmBuf );
233 #if defined(STRUCT_TM_HAS_GMTOFF)
234 /* members of struct tm are corrected by mktime */
235 bias = 0 - pLocalTime->tm_gmtoff;
237 #elif defined(HAS_ALTZONE)
238 /* check if daylight saving time is in effect */
239 bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
240 #else
241 /* exspect daylight saving time to be one hour */
242 bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
243 #endif
245 if ( (sal_Int64) pLocalTimeVal->Seconds + bias > 0 )
247 pSystemTimeVal->Seconds = pLocalTimeVal->Seconds + bias;
248 pSystemTimeVal->Nanosec = pLocalTimeVal->Nanosec;
250 return sal_True;
253 return sal_False;
258 static struct timeval startTime;
259 static sal_Bool bGlobalTimer = sal_False;
261 sal_uInt32 SAL_CALL osl_getGlobalTimer()
263 struct timeval currentTime;
264 sal_uInt32 nSeconds;
266 // FIXME: not thread safe !!
267 if ( bGlobalTimer == sal_False )
269 gettimeofday( &startTime, NULL );
270 bGlobalTimer=sal_True;
273 gettimeofday( &currentTime, NULL );
275 nSeconds = (sal_uInt32)( currentTime.tv_sec - startTime.tv_sec );
277 return ( nSeconds * 1000 ) + (long) (( currentTime.tv_usec - startTime.tv_usec) / 1000 );
280 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */