xref: /AOO41X/main/sal/osl/unx/time.c (revision 647f063d49501903f1667b75f5634541fc603283)
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