1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "system.h"
25
26 #include <osl/diagnose.h>
27 #include <osl/time.h>
28
29 /* FIXME: detection should be done in configure script */
30 #if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) || defined(LINUX)
31 #define STRUCT_TM_HAS_GMTOFF 1
32
33 #elif defined(SOLARIS)
34 #define HAS_ALTZONE 1
35 #endif
36
37 /*--------------------------------------------------
38 * osl_getSystemTime
39 *-------------------------------------------------*/
40
osl_getSystemTime(TimeValue * TimeValue)41 sal_Bool SAL_CALL osl_getSystemTime(TimeValue* TimeValue)
42 {
43 struct timeval tp;
44
45 /* FIXME: use higher resolution */
46 gettimeofday(&tp, NULL);
47
48 TimeValue->Seconds = tp.tv_sec;
49 TimeValue->Nanosec = tp.tv_usec * 1000;
50
51 return (sal_True);
52 }
53
54
55 /*--------------------------------------------------
56 * osl_getDateTimeFromTimeValue
57 *-------------------------------------------------*/
58
osl_getDateTimeFromTimeValue(TimeValue * pTimeVal,oslDateTime * pDateTime)59 sal_Bool SAL_CALL osl_getDateTimeFromTimeValue( TimeValue* pTimeVal, oslDateTime* pDateTime )
60 {
61 struct tm *pSystemTime;
62 struct tm tmBuf;
63 time_t atime;
64
65 atime = (time_t)pTimeVal->Seconds;
66
67 /* Convert time from type time_t to struct tm */
68 pSystemTime = gmtime_r( &atime, &tmBuf );
69
70
71 /* Convert struct tm to struct oslDateTime */
72 if ( pSystemTime != NULL )
73 {
74 pDateTime->NanoSeconds = pTimeVal->Nanosec;
75 pDateTime->Seconds = pSystemTime->tm_sec;
76 pDateTime->Minutes = pSystemTime->tm_min;
77 pDateTime->Hours = pSystemTime->tm_hour;
78 pDateTime->Day = pSystemTime->tm_mday;
79 pDateTime->DayOfWeek = pSystemTime->tm_wday;
80 pDateTime->Month = pSystemTime->tm_mon + 1;
81 pDateTime->Year = pSystemTime->tm_year + 1900;
82
83 return sal_True;
84 }
85
86 return sal_False;
87 }
88
89 /*--------------------------------------------------
90 * osl_getTimeValueFromDateTime
91 *--------------------------------------------------*/
92
osl_getTimeValueFromDateTime(oslDateTime * pDateTime,TimeValue * pTimeVal)93 sal_Bool SAL_CALL osl_getTimeValueFromDateTime( oslDateTime* pDateTime, TimeValue* pTimeVal )
94 {
95 struct tm aTime;
96 time_t nSeconds;
97
98 /* Convert struct oslDateTime to struct tm */
99 aTime.tm_sec = pDateTime->Seconds;
100 aTime.tm_min = pDateTime->Minutes;
101 aTime.tm_hour = pDateTime->Hours;
102 aTime.tm_mday = pDateTime->Day;
103 aTime.tm_wday = pDateTime->DayOfWeek;
104
105 if ( pDateTime->Month > 0 )
106 aTime.tm_mon = pDateTime->Month - 1;
107 else
108 return sal_False;
109
110 if ( pDateTime->Year >= 1900 )
111 aTime.tm_year = pDateTime->Year - 1900;
112 else
113 return sal_False;
114
115 aTime.tm_isdst = -1;
116 aTime.tm_wday = 0;
117 aTime.tm_yday = 0;
118
119 /* Convert time to calendar value */
120 nSeconds = mktime( &aTime );
121
122 /*
123 * mktime expects the struct tm to be in local timezone, so we have to adjust
124 * the returned value to be timezone neutral.
125 */
126
127 if ( nSeconds != (time_t) -1 )
128 {
129 time_t bias;
130
131 /* timezone corrections */
132 tzset();
133
134 #if defined(STRUCT_TM_HAS_GMTOFF)
135 /* members of struct tm are corrected by mktime */
136 bias = 0 - aTime.tm_gmtoff;
137
138 #elif defined(HAS_ALTZONE)
139 /* check if daylight saving time is in effect */
140 bias = aTime.tm_isdst > 0 ? altzone : timezone;
141 #else
142 /* expect daylight saving time to be one hour */
143 bias = aTime.tm_isdst > 0 ? timezone - 3600 : timezone;
144 #endif
145
146 pTimeVal->Seconds = nSeconds;
147 pTimeVal->Nanosec = pDateTime->NanoSeconds;
148
149 if ( nSeconds > bias )
150 pTimeVal->Seconds -= bias;
151
152 return sal_True;
153 }
154
155 return sal_False;
156 }
157
158
159 /*--------------------------------------------------
160 * osl_getLocalTimeFromSystemTime
161 *--------------------------------------------------*/
162
osl_getLocalTimeFromSystemTime(TimeValue * pSystemTimeVal,TimeValue * pLocalTimeVal)163 sal_Bool SAL_CALL osl_getLocalTimeFromSystemTime( TimeValue* pSystemTimeVal, TimeValue* pLocalTimeVal )
164 {
165 struct tm *pLocalTime;
166 struct tm tmBuf;
167 time_t bias;
168 time_t atime;
169
170 atime = (time_t) pSystemTimeVal->Seconds;
171 pLocalTime = localtime_r( &atime, &tmBuf );
172
173 #if defined(STRUCT_TM_HAS_GMTOFF)
174 /* members of struct tm are corrected by mktime */
175 bias = 0 - pLocalTime->tm_gmtoff;
176
177 #elif defined(HAS_ALTZONE)
178 /* check if daylight saving time is in effect */
179 bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
180 #else
181 /* expect daylight saving time to be one hour */
182 bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
183 #endif
184
185 if ( (sal_Int64) pSystemTimeVal->Seconds > bias )
186 {
187 pLocalTimeVal->Seconds = pSystemTimeVal->Seconds - bias;
188 pLocalTimeVal->Nanosec = pSystemTimeVal->Nanosec;
189
190 return sal_True;
191 }
192
193 return sal_False;
194 }
195
196 /*--------------------------------------------------
197 * osl_getSystemTimeFromLocalTime
198 *--------------------------------------------------*/
199
osl_getSystemTimeFromLocalTime(TimeValue * pLocalTimeVal,TimeValue * pSystemTimeVal)200 sal_Bool SAL_CALL osl_getSystemTimeFromLocalTime( TimeValue* pLocalTimeVal, TimeValue* pSystemTimeVal )
201 {
202 struct tm *pLocalTime;
203 struct tm tmBuf;
204 time_t bias;
205 time_t atime;
206
207 atime = (time_t) pLocalTimeVal->Seconds;
208
209 /* Convert atime, which is a local time, to its GMT equivalent. Then, get
210 * the timezone offset for the local time for the GMT equivalent time. Note
211 * that we cannot directly use local time to determine the timezone offset
212 * because GMT is the only reliable time that we can determine timezone
213 * offset from.
214 */
215
216 atime = mktime( gmtime_r( &atime, &tmBuf ) );
217 pLocalTime = localtime_r( &atime, &tmBuf );
218
219 #if defined(STRUCT_TM_HAS_GMTOFF)
220 /* members of struct tm are corrected by mktime */
221 bias = 0 - pLocalTime->tm_gmtoff;
222
223 #elif defined(HAS_ALTZONE)
224 /* check if daylight saving time is in effect */
225 bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
226 #else
227 /* expect daylight saving time to be one hour */
228 bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
229 #endif
230
231 if ( (sal_Int64) pLocalTimeVal->Seconds + bias > 0 )
232 {
233 pSystemTimeVal->Seconds = pLocalTimeVal->Seconds + bias;
234 pSystemTimeVal->Nanosec = pLocalTimeVal->Nanosec;
235
236 return sal_True;
237 }
238
239 return sal_False;
240 }
241
242
243
244 static struct timeval startTime;
245 static sal_Bool bGlobalTimer = sal_False;
246
osl_getGlobalTimer()247 sal_uInt32 SAL_CALL osl_getGlobalTimer()
248 {
249 struct timeval currentTime;
250 sal_uInt32 nSeconds;
251
252 // FIXME: not thread safe !!
253 if ( bGlobalTimer == sal_False )
254 {
255 gettimeofday( &startTime, NULL );
256 bGlobalTimer=sal_True;
257 }
258
259 gettimeofday( ¤tTime, NULL );
260
261 nSeconds = (sal_uInt32)( currentTime.tv_sec - startTime.tv_sec );
262
263 return ( nSeconds * 1000 ) + (long) (( currentTime.tv_usec - startTime.tv_usec) / 1000 );
264 }
265