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 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 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 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 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 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 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( ¤tTime, 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