1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 19 #include "oscl_time.h" 20 #include "oscl_assert.h" 21 #include "oscl_stdstring.h" 22 23 #if (OSCL_DISABLE_INLINES) 24 #include "oscl_time.inl" 25 #endif 26 27 28 //---OSCL_HAS_UNIX_TIME_FUNCS---// 29 30 const uint32 origin_offset = 2208988800U; 31 const uint64 freq_conv = 281474977; 32 33 int NTPTime::set_to_current_time() 34 { 35 struct timeval tv; 36 uint64 tmp; 37 38 // get the current time 39 // This gives back time since 0h Jan 1, 1970 40 gettimeofday(&tv, 0); 41 42 timevalue = origin_offset; 43 // now convert to proper time origin 44 timevalue += tv.tv_sec; 45 46 timevalue <<= 32; 47 48 // now convert the frequency of the fractional part 49 // from usec to 2^32 ticks/sec. 50 if (tv.tv_usec > 0) 51 { 52 tmp = (tv.tv_usec * freq_conv) >> 16; 53 timevalue += tmp; 54 } 55 56 return 0; 57 } 58 59 60 NTPTime::NTPTime(const TimeValue& t) 61 { 62 const timeval *pTimeVal = t.getBasicTimeStruct(); 63 64 timevalue = origin_offset; 65 // now convert to proper time origin 66 timevalue += pTimeVal->tv_sec; 67 68 timevalue <<= 32; 69 70 71 // now convert the frequency of the fractional part 72 // from usec to 2^32 ticks/sec. 73 uint64 tmp = (pTimeVal->tv_usec * freq_conv) >> 16; 74 75 76 timevalue += tmp; 77 } 78 79 80 int DayIndexFromDate(int year, int month, int day) 81 { 82 // return index (0=Sunday, 1=Monday... etc 83 84 int days_so_far[] = { 0 , 31 , 59 , 90 , 120, 151, 85 181, 212, 243, 273, 304, 334 86 }; 87 if (month > 12 || month < 0 || year < 1 || day < 1 || day > 31) 88 return 0; // bad value(s) 89 90 int day_index = ((year - 1) * 365 + 91 (year - 1) / 4 + 92 days_so_far[month-1] + 93 day + 94 (((month > 2) && !(year % 4)) ? 1 : 0) 95 ) % 7; 96 return (day_index == 0) ? 6 : (day_index - 1); 97 } 98 99 static const char* const months[] = { "Jan", "Feb", "Mar", "Apr", "May", 100 "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 101 "" 102 }; 103 static const char* const days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; 104 105 OSCL_EXPORT_REF void PV8601ToRFC822(PV8601timeStrBuf pv8601_buffer, CtimeStrBuf ctime_buffer) 106 { 107 // Convert from PV8601 Format (20010805T185430.000Z) 108 // to RFC822 Format (Sun Aug 5 18:54:30 2001) 109 // No <time.h> functions will be used because this code must run on 110 // all platforms. 111 //---OSCL_HAS_ANSI_STRING_SUPPORT---// 112 if ((PV8601TIME_BUFFER_SIZE - 1) != strlen(pv8601_buffer)) 113 { 114 ctime_buffer[0] = 0; 115 return; 116 } 117 118 char buf[5]; 119 120 int year, mon, day, hour, min, sec; 121 122 strncpy(buf, pv8601_buffer, 4); 123 buf[4] = 0; 124 year = atoi(buf); 125 126 buf[2] = 0; 127 strncpy(buf, pv8601_buffer + 4, 2); 128 mon = atoi(buf); 129 if (mon <= 0 || mon > 13) 130 mon = 13; 131 strncpy(buf, pv8601_buffer + 6, 2); 132 day = atoi(buf); 133 strncpy(buf, pv8601_buffer + 9, 2); 134 hour = atoi(buf); 135 strncpy(buf, pv8601_buffer + 11, 2); 136 min = atoi(buf); 137 strncpy(buf, pv8601_buffer + 13, 2); 138 sec = atoi(buf); 139 140 sprintf(ctime_buffer, 141 "%s %s %2d %02d:%02d:%02d %04d", 142 days[DayIndexFromDate(year, mon, day)], 143 months[mon-1], 144 day, hour, min, sec, year); 145 146 } 147 148 OSCL_EXPORT_REF void RFC822ToPV8601(CtimeStrBuf ctime_buffer, PV8601timeStrBuf pv8601_buffer) 149 { 150 // Convert from RFC822 Format (Sun Aug 5 18:54:30 2001) 151 // to PV8601 Format (20010805T185430.000Z) 152 // No <time.h> functions will be used because this code must run on 153 // all platforms. 154 155 //---OSCL_HAS_ANSI_STRING_SUPPORT--- or ..// 156 const char *ptr = ctime_buffer; 157 158 int mon = 0, day, hour, min, sec; 159 160 for (int i = 0; *months[i]; i++) 161 { 162 if (!strncmp(ptr + 4, months[i], 3)) 163 { 164 mon = i + 1; 165 break; 166 } 167 } 168 169 day = atoi(*(ptr + 8) == ' ' ? (ptr + 9) : (ptr + 8)); 170 hour = atoi(ptr + 11); 171 min = atoi(ptr + 14); 172 sec = atoi(ptr + 17); 173 174 sprintf(pv8601_buffer, 175 "%04d%02d%02dT%02d%02d%02d.000Z", 176 atoi(ptr + 20), // year 177 mon, day, hour, min, sec); 178 179 } 180 181 182 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 183 //! get_rfc822_gmtime_str not supported on all platforms 184 /*! 185 Notes: Symbian implementation feasible but not done. 186 */ 187 188 OSCL_EXPORT_REF char *TimeValue::get_rfc822_gmtime_str(int max_time_strlen, 189 char *time_str) 190 { 191 //---OSCL_HAS_UNIX_TIME_FUNCS---// 192 struct tm *timeptr; 193 struct tm buffer; 194 timeptr = gmtime_r(&ts.tv_sec, &buffer); 195 196 int length = snprintf(time_str, max_time_strlen, 197 "%s, %02d %s %04d %02d:%02d:%02d GMT", 198 days[timeptr->tm_wday], timeptr->tm_mday, 199 months[timeptr->tm_mon], timeptr->tm_year + 1900, 200 timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec); 201 if (length < 0 || length > max_time_strlen) 202 { 203 time_str[0] = NULL_TERM_CHAR; 204 } 205 return time_str; 206 } 207 208 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 209 //! get_str_ctime not supported on all platforms 210 /*! 211 Notes: Symbian implementation of obsolete function get_str_time 212 modified to fit format returned by ctime 213 */ 214 OSCL_EXPORT_REF char *TimeValue::get_str_ctime(CtimeStrBuf ctime_buffer) 215 { 216 //---OSCL_HAS_UNIX_TIME_FUNCS---// 217 // Uses timeval basic time structure 218 char *ptr = ctime_r(&ts.tv_sec, ctime_buffer); 219 220 char *ptr_end = strchr(ptr, '\n'); 221 if (ptr_end) *ptr_end = '\0'; 222 return ptr; 223 224 } 225 226 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 227 OSCL_EXPORT_REF int TimeValue::get_pv8601_str_time(PV8601timeStrBuf time_strbuf) 228 { 229 //---OSCL_HAS_UNIX_TIME_FUNCS---// 230 int num_chars = 0; 231 struct tm *timeptr; 232 struct tm buffer; 233 234 timeptr = gmtime_r(&ts.tv_sec, &buffer); 235 236 if ((num_chars = strftime(time_strbuf, sizeof(PV8601timeStrBuf), 237 "%Y%m%dT%H%M%S", timeptr)) == 0) 238 time_strbuf[0] = NULL_TERM_CHAR; 239 else 240 num_chars += snprintf(time_strbuf + strlen(time_strbuf), 241 sizeof(PV8601timeStrBuf) - num_chars, 242 ".%03dZ", (int)(ts.tv_usec / 1000)); 243 244 return num_chars; 245 246 } 247 248 249 250