xref: /aoo4110/main/sal/osl/unx/time.c (revision b1cdbd2c)
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 
25 #include "system.h"
26 
27 #include <osl/diagnose.h>
28 #include <osl/time.h>
29 
30 /* FIXME: detection should be done in configure script */
31 #if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) || defined(LINUX)
32 #define STRUCT_TM_HAS_GMTOFF 1
33 
34 #elif defined(SOLARIS)
35 #define HAS_ALTZONE 1
36 #endif
37 
38 /*--------------------------------------------------
39  * osl_getSystemTime
40  *-------------------------------------------------*/
41 
osl_getSystemTime(TimeValue * TimeValue)42 sal_Bool SAL_CALL osl_getSystemTime(TimeValue* TimeValue)
43 {
44 	struct timeval tp;
45 
46     /* FIXME: use higher resolution */
47 	gettimeofday(&tp, NULL);
48 
49 	TimeValue->Seconds = tp.tv_sec;
50 	TimeValue->Nanosec = tp.tv_usec * 1000;
51 
52 	return (sal_True);
53 }
54 
55 
56 /*--------------------------------------------------
57  * osl_getDateTimeFromTimeValue
58  *-------------------------------------------------*/
59 
osl_getDateTimeFromTimeValue(TimeValue * pTimeVal,oslDateTime * pDateTime)60 sal_Bool SAL_CALL osl_getDateTimeFromTimeValue( TimeValue* pTimeVal, oslDateTime* pDateTime )
61 {
62 	struct tm *pSystemTime;
63     struct tm tmBuf;
64 	time_t atime;
65 
66 	atime = (time_t)pTimeVal->Seconds;
67 
68 	/* Convert time from type time_t to struct tm */
69 	pSystemTime = gmtime_r( &atime, &tmBuf );
70 
71 
72 	/* Convert struct tm to struct oslDateTime */
73 	if ( pSystemTime != NULL )
74 	{
75 		pDateTime->NanoSeconds	=	pTimeVal->Nanosec;
76 		pDateTime->Seconds		=	pSystemTime->tm_sec;
77 		pDateTime->Minutes		=	pSystemTime->tm_min;
78 		pDateTime->Hours		=	pSystemTime->tm_hour;
79 		pDateTime->Day			=	pSystemTime->tm_mday;
80 		pDateTime->DayOfWeek	=	pSystemTime->tm_wday;
81 		pDateTime->Month		=	pSystemTime->tm_mon + 1;
82 		pDateTime->Year			=	pSystemTime->tm_year  + 1900;
83 
84 		return sal_True;
85 	}
86 
87 	return sal_False;
88 }
89 
90 /*--------------------------------------------------
91  * osl_getTimeValueFromDateTime
92  *--------------------------------------------------*/
93 
osl_getTimeValueFromDateTime(oslDateTime * pDateTime,TimeValue * pTimeVal)94 sal_Bool SAL_CALL osl_getTimeValueFromDateTime( oslDateTime* pDateTime, TimeValue* pTimeVal )
95 {
96 	struct tm	aTime;
97 	time_t		nSeconds;
98 
99 	/* Convert struct oslDateTime to struct tm */
100 	aTime.tm_sec  = pDateTime->Seconds;
101 	aTime.tm_min  = pDateTime->Minutes;
102 	aTime.tm_hour = pDateTime->Hours;
103 	aTime.tm_mday = pDateTime->Day;
104 	aTime.tm_wday = pDateTime->DayOfWeek;
105 
106 	if ( pDateTime->Month > 0 )
107 		aTime.tm_mon = pDateTime->Month - 1;
108 	else
109 		return sal_False;
110 
111 	if ( pDateTime->Year >= 1900 )
112 		aTime.tm_year = pDateTime->Year - 1900;
113 	else
114 		return sal_False;
115 
116     aTime.tm_isdst = -1;
117 	aTime.tm_wday  = 0;
118 	aTime.tm_yday  = 0;
119 
120 	/* Convert time to calendar value */
121 	nSeconds = mktime( &aTime );
122 
123     /*
124      * mktime expects the struct tm to be in local timezone, so we have to adjust
125      * the returned value to be timezone neutral.
126      */
127 
128 	if ( nSeconds != (time_t) -1 )
129 	{
130         time_t bias;
131 
132 		/* timezone corrections */
133 		tzset();
134 
135 #if defined(STRUCT_TM_HAS_GMTOFF)
136         /* members of struct tm are corrected by mktime */
137         bias = 0 - aTime.tm_gmtoff;
138 
139 #elif defined(HAS_ALTZONE)
140         /* check if daylight saving time is in effect */
141         bias = aTime.tm_isdst > 0 ? altzone : timezone;
142 #else
143         /* exspect daylight saving time to be one hour */
144         bias = aTime.tm_isdst > 0 ? timezone - 3600 : timezone;
145 #endif
146 
147         pTimeVal->Seconds = nSeconds;
148 		pTimeVal->Nanosec = pDateTime->NanoSeconds;
149 
150         if ( nSeconds > bias )
151 		    pTimeVal->Seconds -= bias;
152 
153 		return sal_True;
154 	}
155 
156 	return sal_False;
157 }
158 
159 
160 /*--------------------------------------------------
161  * osl_getLocalTimeFromSystemTime
162  *--------------------------------------------------*/
163 
osl_getLocalTimeFromSystemTime(TimeValue * pSystemTimeVal,TimeValue * pLocalTimeVal)164 sal_Bool SAL_CALL osl_getLocalTimeFromSystemTime( TimeValue* pSystemTimeVal, TimeValue* pLocalTimeVal )
165 {
166     struct tm *pLocalTime;
167     struct tm tmBuf;
168     time_t bias;
169 	time_t atime;
170 
171     atime = (time_t) pSystemTimeVal->Seconds;
172     pLocalTime = localtime_r( &atime, &tmBuf );
173 
174 #if defined(STRUCT_TM_HAS_GMTOFF)
175     /* members of struct tm are corrected by mktime */
176     bias = 0 - pLocalTime->tm_gmtoff;
177 
178 #elif defined(HAS_ALTZONE)
179     /* check if daylight saving time is in effect */
180     bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
181 #else
182     /* exspect daylight saving time to be one hour */
183     bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
184 #endif
185 
186 	if ( (sal_Int64) pSystemTimeVal->Seconds > bias )
187 	{
188 		pLocalTimeVal->Seconds = pSystemTimeVal->Seconds - bias;
189 		pLocalTimeVal->Nanosec = pSystemTimeVal->Nanosec;
190 
191 		return sal_True;
192 	}
193 
194 	return sal_False;
195 }
196 
197 /*--------------------------------------------------
198  * osl_getSystemTimeFromLocalTime
199  *--------------------------------------------------*/
200 
osl_getSystemTimeFromLocalTime(TimeValue * pLocalTimeVal,TimeValue * pSystemTimeVal)201 sal_Bool SAL_CALL osl_getSystemTimeFromLocalTime( TimeValue* pLocalTimeVal, TimeValue* pSystemTimeVal )
202 {
203 	struct tm *pLocalTime;
204     struct tm tmBuf;
205 	time_t bias;
206 	time_t atime;
207 
208     atime = (time_t) pLocalTimeVal->Seconds;
209 
210     /* Convert atime, which is a local time, to it's GMT equivalent. Then, get
211      * the timezone offset for the local time for the GMT equivalent time. Note
212      * that we cannot directly use local time to determine the timezone offset
213      * because GMT is the only reliable time that we can determine timezone
214      * offset from.
215      */
216 
217     atime = mktime( gmtime_r( &atime, &tmBuf ) );
218     pLocalTime = localtime_r( &atime, &tmBuf );
219 
220 #if defined(STRUCT_TM_HAS_GMTOFF)
221     /* members of struct tm are corrected by mktime */
222     bias = 0 - pLocalTime->tm_gmtoff;
223 
224 #elif defined(HAS_ALTZONE)
225     /* check if daylight saving time is in effect */
226     bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
227 #else
228     /* exspect daylight saving time to be one hour */
229     bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
230 #endif
231 
232 	if ( (sal_Int64) pLocalTimeVal->Seconds + bias > 0 )
233 	{
234 		pSystemTimeVal->Seconds = pLocalTimeVal->Seconds + bias;
235 		pSystemTimeVal->Nanosec = pLocalTimeVal->Nanosec;
236 
237 		return sal_True;
238 	}
239 
240 	return sal_False;
241 }
242 
243 
244 
245 static struct timeval startTime;
246 static sal_Bool bGlobalTimer = sal_False;
247 
osl_getGlobalTimer()248 sal_uInt32 SAL_CALL osl_getGlobalTimer()
249 {
250   struct timeval currentTime;
251   sal_uInt32 nSeconds;
252 
253   // FIXME: not thread safe !!
254   if ( bGlobalTimer == sal_False )
255   {
256       gettimeofday( &startTime, NULL );
257       bGlobalTimer=sal_True;
258   }
259 
260   gettimeofday( &currentTime, NULL );
261 
262   nSeconds = (sal_uInt32)( currentTime.tv_sec - startTime.tv_sec );
263 
264   return ( nSeconds * 1000 ) + (long) (( currentTime.tv_usec - startTime.tv_usec) / 1000 );
265 }
266