xref: /aoo42x/main/sal/osl/os2/time.c (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 #include "system.h"
30 
31 #include <osl/diagnose.h>
32 #include <osl/time.h>
33 
34 /* FIXME: detection should be done in configure script */
35 #if defined(MACOSX) || defined(FREEBSD) || defined(NETBSD) || defined(LINUX)
36 #define STRUCT_TM_HAS_GMTOFF 1
37 
38 #elif defined(SOLARIS)
39 #define HAS_ALTZONE 1
40 #endif
41 
42 /*--------------------------------------------------
43  * osl_getSystemTime
44  *-------------------------------------------------*/
45 
46 sal_Bool SAL_CALL osl_getSystemTime(TimeValue* TimeValue)
47 {
48 	struct timeval tp;
49 
50     /* FIXME: use higher resolution */
51 	gettimeofday(&tp, NULL);
52 
53 	TimeValue->Seconds = tp.tv_sec;
54 	TimeValue->Nanosec = tp.tv_usec * 1000;
55 
56 	return (sal_True);
57 }
58 
59 
60 /*--------------------------------------------------
61  * osl_getDateTimeFromTimeValue
62  *-------------------------------------------------*/
63 
64 sal_Bool SAL_CALL osl_getDateTimeFromTimeValue( TimeValue* pTimeVal, oslDateTime* pDateTime )
65 {
66 	struct tm *pSystemTime;
67     struct tm tmBuf;
68 	time_t atime;
69 
70 	atime = (time_t)pTimeVal->Seconds;
71 
72 	/* Convert time from type time_t to struct tm */
73 	pSystemTime = gmtime_r( &atime, &tmBuf );
74 
75 
76 	/* Convert struct tm to struct oslDateTime */
77 	if ( pSystemTime != NULL )
78 	{
79 		pDateTime->NanoSeconds	=	pTimeVal->Nanosec;
80 		pDateTime->Seconds		=	pSystemTime->tm_sec;
81 		pDateTime->Minutes		=	pSystemTime->tm_min;
82 		pDateTime->Hours		=	pSystemTime->tm_hour;
83 		pDateTime->Day			=	pSystemTime->tm_mday;
84 		pDateTime->DayOfWeek	=	pSystemTime->tm_wday;
85 		pDateTime->Month		=	pSystemTime->tm_mon + 1;
86 		pDateTime->Year			=	pSystemTime->tm_year  + 1900;
87 
88 		return sal_True;
89 	}
90 
91 	return sal_False;
92 }
93 
94 /*--------------------------------------------------
95  * osl_getTimeValueFromDateTime
96  *--------------------------------------------------*/
97 
98 sal_Bool SAL_CALL osl_getTimeValueFromDateTime( oslDateTime* pDateTime, TimeValue* pTimeVal )
99 {
100 	struct tm	aTime;
101 	time_t		nSeconds;
102 
103 	/* Convert struct oslDateTime to struct tm */
104 	aTime.tm_sec  = pDateTime->Seconds;
105 	aTime.tm_min  = pDateTime->Minutes;
106 	aTime.tm_hour = pDateTime->Hours;
107 	aTime.tm_mday = pDateTime->Day;
108 	aTime.tm_wday = pDateTime->DayOfWeek;
109 
110 	if ( pDateTime->Month > 0 )
111 		aTime.tm_mon = pDateTime->Month - 1;
112 	else
113 		return sal_False;
114 
115 	if ( pDateTime->Year >= 1900 )
116 		aTime.tm_year = pDateTime->Year - 1900;
117 	else
118 		return sal_False;
119 
120     aTime.tm_isdst = -1;
121 	aTime.tm_wday  = 0;
122 	aTime.tm_yday  = 0;
123 
124 	/* Convert time to calendar value */
125 	nSeconds = mktime( &aTime );
126 
127     /*
128      * mktime expects the struct tm to be in local timezone, so we have to adjust
129      * the returned value to be timezone neutral.
130      */
131 
132 	if ( nSeconds != (time_t) -1 )
133 	{
134         time_t bias;
135 
136 		/* timezone corrections */
137 		tzset();
138 
139 #if defined(STRUCT_TM_HAS_GMTOFF)
140         /* members of struct tm are corrected by mktime */
141         bias = 0 - aTime.tm_gmtoff;
142 
143 #elif defined(HAS_ALTZONE)
144         /* check if daylight saving time is in effect */
145         bias = aTime.tm_isdst > 0 ? altzone : timezone;
146 #else
147         /* exspect daylight saving time to be one hour */
148         bias = aTime.tm_isdst > 0 ? timezone - 3600 : timezone;
149 #endif
150 
151         pTimeVal->Seconds = nSeconds;
152 		pTimeVal->Nanosec = pDateTime->NanoSeconds;
153 
154         if ( nSeconds > bias )
155 		    pTimeVal->Seconds -= bias;
156 
157 		return sal_True;
158 	}
159 
160 	return sal_False;
161 }
162 
163 
164 /*--------------------------------------------------
165  * osl_getLocalTimeFromSystemTime
166  *--------------------------------------------------*/
167 
168 sal_Bool SAL_CALL osl_getLocalTimeFromSystemTime( TimeValue* pSystemTimeVal, TimeValue* pLocalTimeVal )
169 {
170     struct tm *pLocalTime;
171     struct tm tmBuf;
172     time_t bias;
173 	time_t atime;
174 
175     atime = (time_t) pSystemTimeVal->Seconds;
176     pLocalTime = localtime_r( &atime, &tmBuf );
177 
178 #if defined(STRUCT_TM_HAS_GMTOFF)
179     /* members of struct tm are corrected by mktime */
180     bias = 0 - pLocalTime->tm_gmtoff;
181 
182 #elif defined(HAS_ALTZONE)
183     /* check if daylight saving time is in effect */
184     bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
185 #else
186     /* exspect daylight saving time to be one hour */
187     bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
188 #endif
189 
190 	if ( (sal_Int64) pSystemTimeVal->Seconds > bias )
191 	{
192 		pLocalTimeVal->Seconds = pSystemTimeVal->Seconds - bias;
193 		pLocalTimeVal->Nanosec = pSystemTimeVal->Nanosec;
194 
195 		return sal_True;
196 	}
197 
198 	return sal_False;
199 }
200 
201 /*--------------------------------------------------
202  * osl_getSystemTimeFromLocalTime
203  *--------------------------------------------------*/
204 
205 sal_Bool SAL_CALL osl_getSystemTimeFromLocalTime( TimeValue* pLocalTimeVal, TimeValue* pSystemTimeVal )
206 {
207 	struct tm *pLocalTime;
208     struct tm tmBuf;
209 	time_t bias;
210 	time_t atime;
211 
212     atime = (time_t) pLocalTimeVal->Seconds;
213 
214     /* Convert atime, which is a local time, to it's GMT equivalent. Then, get
215      * the timezone offset for the local time for the GMT equivalent time. Note
216      * that we cannot directly use local time to determine the timezone offset
217      * because GMT is the only reliable time that we can determine timezone
218      * offset from.
219      */
220 
221     atime = mktime( gmtime_r( &atime, &tmBuf ) );
222     pLocalTime = localtime_r( &atime, &tmBuf );
223 
224 #if defined(STRUCT_TM_HAS_GMTOFF)
225     /* members of struct tm are corrected by mktime */
226     bias = 0 - pLocalTime->tm_gmtoff;
227 
228 #elif defined(HAS_ALTZONE)
229     /* check if daylight saving time is in effect */
230     bias = pLocalTime->tm_isdst > 0 ? altzone : timezone;
231 #else
232     /* exspect daylight saving time to be one hour */
233     bias = pLocalTime->tm_isdst > 0 ? timezone - 3600 : timezone;
234 #endif
235 
236 	if ( (sal_Int64) pLocalTimeVal->Seconds + bias > 0 )
237 	{
238 		pSystemTimeVal->Seconds = pLocalTimeVal->Seconds + bias;
239 		pSystemTimeVal->Nanosec = pLocalTimeVal->Nanosec;
240 
241 		return sal_True;
242 	}
243 
244 	return sal_False;
245 }
246 
247 
248 
249 static struct timeval startTime;
250 static sal_Bool bGlobalTimer = sal_False;
251 
252 sal_uInt32 SAL_CALL osl_getGlobalTimer()
253 {
254   struct timeval currentTime;
255   sal_uInt32 nSeconds;
256 
257   // FIXME: not thread safe !!
258   if ( bGlobalTimer == sal_False )
259   {
260       gettimeofday( &startTime, NULL );
261       bGlobalTimer=sal_True;
262   }
263 
264   gettimeofday( &currentTime, NULL );
265 
266   nSeconds = (sal_uInt32)( currentTime.tv_sec - startTime.tv_sec );
267 
268   return ( nSeconds * 1000 ) + (long) (( currentTime.tv_usec - startTime.tv_usec) / 1000 );
269 }
270