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 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 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 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 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 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 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