/home/ntakagi/work/STLport-5.1.5/src/time_facets.cppGo to the documentation of this file.00001 /* 00002 * Copyright (c) 1999 00003 * Silicon Graphics Computer Systems, Inc. 00004 * 00005 * Copyright (c) 1999 00006 * Boris Fomitchev 00007 * 00008 * This material is provided "as is", with absolutely no warranty expressed 00009 * or implied. Any use is at your own risk. 00010 * 00011 * Permission to use or copy this software for any purpose is hereby granted 00012 * without fee, provided the above notices are retained on all copies. 00013 * Permission to modify the code and to distribute modified code is granted, 00014 * provided the above notices are retained, and a notice that the code was 00015 * modified is included with the above copyright notice. 00016 * 00017 */ 00018 00019 #include "stlport_prefix.h" 00020 00021 #include <cstdio> 00022 #include <locale> 00023 #include <istream> 00024 #include <cstdio> 00025 00026 #include "c_locale.h" 00027 00028 _STLP_BEGIN_NAMESPACE 00029 00030 _STLP_MOVE_TO_PRIV_NAMESPACE 00031 00032 // default "C" values for month and day names 00033 00034 const char default_dayname[][14] = { 00035 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 00036 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", 00037 "Friday", "Saturday"}; 00038 00039 const char default_monthname[][24] = { 00040 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 00041 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 00042 "January", "February", "March", "April", "May", "June", 00043 "July", "August", "September", "October", "November", "December"}; 00044 00045 // _Init_time_info: initialize table with 00046 // "C" values (note these are not defined in the C standard, so this 00047 // is somewhat arbitrary). 00048 00049 void _STLP_CALL _Init_timeinfo(_Time_Info& table) { 00050 int i; 00051 for (i = 0; i < 14; ++i) 00052 table._M_dayname[i] = default_dayname[i]; 00053 for (i = 0; i < 24; ++i) 00054 table._M_monthname[i] = default_monthname[i]; 00055 table._M_am_pm[0] = "AM"; 00056 table._M_am_pm[1] = "PM"; 00057 table._M_time_format = "%H:%M:%S"; 00058 table._M_date_format = "%m/%d/%y"; 00059 table._M_date_time_format = "%m/%d/%y"; 00060 } 00061 00062 void _STLP_CALL _Init_timeinfo(_Time_Info& table, _Locale_time * time) { 00063 if(!time) 00064 locale::_M_throw_runtime_error(); 00065 00066 int i; 00067 for (i = 0; i < 7; ++i) 00068 table._M_dayname[i] = _Locale_abbrev_dayofweek(time, i); 00069 for (i = 0; i < 7; ++i) 00070 table._M_dayname[i+7] = _Locale_full_dayofweek(time, i); 00071 for (i = 0; i < 12; ++i) 00072 table._M_monthname[i] = _Locale_abbrev_monthname(time, i); 00073 for (i = 0; i < 12; ++i) 00074 table._M_monthname[i+12] = _Locale_full_monthname(time, i); 00075 table._M_am_pm[0] = _Locale_am_str(time); 00076 table._M_am_pm[1] = _Locale_pm_str(time); 00077 table._M_time_format = _Locale_t_fmt(time); 00078 if ( table._M_time_format == "%T" ) { 00079 table._M_time_format = "%H:%M:%S"; 00080 } else if ( table._M_time_format == "%r" ) { 00081 table._M_time_format = "%I:%M:%S %p"; 00082 } else if ( table._M_time_format == "%R" ) { 00083 table._M_time_format = "%H:%M"; 00084 } 00085 table._M_date_format = _Locale_d_fmt(time); 00086 table._M_date_time_format = _Locale_d_t_fmt(time); 00087 table._M_long_date_format = _Locale_long_d_fmt(time); 00088 table._M_long_date_time_format = _Locale_long_d_t_fmt(time); 00089 } 00090 00091 inline char* __subformat(const string& format, char*& buf, size_t buf_size, 00092 const _Time_Info& table, const tm* t) { 00093 const char * cp = format.data(); 00094 const char * cp_end = cp + format.size(); 00095 while (cp != cp_end) { 00096 if (*cp == '%') { 00097 char mod = 0; 00098 ++cp; 00099 if(*cp == '#') { 00100 mod = *cp; ++cp; 00101 } 00102 char *former_buf = buf; 00103 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t); 00104 buf_size -= (buf - former_buf); 00105 } else 00106 *buf++ = *cp++; 00107 } 00108 return buf; 00109 } 00110 00111 #if defined (__GNUC__) 00112 /* The number of days from the first day of the first ISO week of this 00113 year to the year day YDAY with week day WDAY. ISO weeks start on 00114 Monday; the first ISO week has the year's first Thursday. YDAY may 00115 be as small as YDAY_MINIMUM. */ 00116 # define __ISO_WEEK_START_WDAY 1 /* Monday */ 00117 # define __ISO_WEEK1_WDAY 4 /* Thursday */ 00118 # define __YDAY_MINIMUM (-366) 00119 # define __TM_YEAR_BASE 1900 00120 static int 00121 __iso_week_days(int yday, int wday) { 00122 /* Add enough to the first operand of % to make it nonnegative. */ 00123 int big_enough_multiple_of_7 = (-__YDAY_MINIMUM / 7 + 2) * 7; 00124 return (yday 00125 - (yday - wday + __ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 00126 + __ISO_WEEK1_WDAY - __ISO_WEEK_START_WDAY); 00127 } 00128 00129 # define __is_leap(year)\ 00130 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) 00131 00132 #endif 00133 00134 #define __hour12(hour) \ 00135 (((hour) % 12 == 0) ? (12) : (hour) % 12) 00136 00137 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00138 # define _STLP_SPRINTF(B, BS, F, D) sprintf(B, F, D) 00139 #else 00140 # define _STLP_SPRINTF(B, BS, F, D) sprintf_s(B, BS, F, D) 00141 #endif 00142 00143 char * _STLP_CALL __write_formatted_time(char* buf, size_t buf_size, char format, char modifier, 00144 const _Time_Info& table, const tm* t) { 00145 switch (format) { 00146 case 'a': 00147 return copy(table._M_dayname[t->tm_wday].begin(), 00148 table._M_dayname[t->tm_wday].end(), 00149 buf); 00150 00151 case 'A': 00152 return copy(table._M_dayname[t->tm_wday+7].begin(), 00153 table._M_dayname[t->tm_wday+7].end(), 00154 buf); 00155 00156 case 'b': 00157 return copy(table._M_monthname[t->tm_mon].begin(), 00158 table._M_monthname[t->tm_mon].end(), 00159 buf); 00160 00161 case 'B': 00162 return copy(table._M_monthname[t->tm_mon+12].begin(), 00163 table._M_monthname[t->tm_mon+12].end(), 00164 buf); 00165 00166 case 'c': { 00167 const char *cp = (modifier != '#') ? 00168 table._M_date_time_format.data() : 00169 table._M_long_date_time_format.data(); 00170 const char* cp_end = cp + 00171 ((modifier != '#') ? table._M_date_time_format.size() : 00172 table._M_long_date_time_format.size() ); 00173 char mod; 00174 while (cp != cp_end) { 00175 if (*cp == '%') { 00176 ++cp; if(*cp == '#') mod = *cp++; else mod = 0; 00177 char *buf_pos = buf; 00178 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t); 00179 buf_size -= (buf - buf_pos); 00180 } 00181 else { 00182 *buf++ = *cp++; --buf_size; 00183 } 00184 } 00185 return buf; 00186 } 00187 00188 case 'd': 00189 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_mday); 00190 return ((long)t->tm_mday < 10L && modifier == '#')?buf+1:buf + 2; 00191 00192 case 'e': 00193 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_mday); 00194 return buf + 2; 00195 00196 case 'H': 00197 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_hour); 00198 return ((long)t->tm_hour < 10L && modifier == '#')?buf+1:buf + 2; 00199 00200 case 'I': 00201 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)__hour12(t->tm_hour)); 00202 return ((long)__hour12(t->tm_hour) < 10L && modifier == '#')?buf+1:buf + 2; 00203 00204 case 'j': 00205 return __write_integer(buf, 0, (long)((long)t->tm_yday + 1)); 00206 00207 case 'm': 00208 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_mon + 1); 00209 return ((long)(t->tm_mon + 1) < 10L && modifier == '#')?buf+1:buf + 2; 00210 00211 case 'M': 00212 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_min); 00213 return ((long)t->tm_min < 10L && modifier == '#')?buf+1:buf + 2; 00214 00215 case 'p': 00216 return copy(table._M_am_pm[t->tm_hour/12].begin(), 00217 table._M_am_pm[t->tm_hour/12].end(), 00218 buf); 00219 00220 case 'S': // pad with zeros 00221 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_sec); 00222 return ((long)t->tm_sec < 10L && modifier == '#')?buf+1:buf + 2; 00223 00224 case 'U': 00225 return __write_integer(buf, 0, 00226 long((t->tm_yday - t->tm_wday + 7) / 7)); 00227 // break; 00228 00229 case 'w': 00230 return __write_integer(buf, 0, (long)t->tm_wday); 00231 // break; 00232 00233 case 'W': 00234 return __write_integer(buf, 0, 00235 (long)(t->tm_wday == 0 ? (t->tm_yday + 1) / 7 : 00236 (t->tm_yday + 8 - t->tm_wday) / 7)); 00237 00238 case'x': { 00239 const char * cp = (modifier != '#') ? table._M_date_format.data(): 00240 table._M_long_date_format.data(); 00241 const char* cp_end = (modifier != '#') ? cp + table._M_date_format.size(): 00242 cp + table._M_long_date_format.size(); 00243 char mod; 00244 while (cp != cp_end) { 00245 if (*cp == '%') { 00246 ++cp; if(*cp == '#') mod = *cp++; else mod = 0; 00247 char *buf_pos = buf; 00248 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t); 00249 buf_size -= (buf - buf_pos); 00250 } 00251 else { 00252 *buf++ = *cp++; --buf_size; 00253 } 00254 } 00255 return buf; 00256 } 00257 00258 case 'X': { 00259 const char * cp = table._M_time_format.data(); 00260 const char* cp_end = cp + table._M_time_format.size(); 00261 char mod; 00262 while (cp != cp_end) { 00263 if (*cp == '%') { 00264 ++cp; if(*cp == '#') mod = *cp++; else mod = 0; 00265 char *buf_pos = buf; 00266 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t); 00267 buf_size -= (buf - buf_pos); 00268 } 00269 else { 00270 *buf++ = *cp++; --buf_size; 00271 } 00272 } 00273 return buf; 00274 } 00275 case 'y': 00276 return __write_integer(buf, 0, (long)((long)(t->tm_year + 1900) % 100)); 00277 00278 case 'Y': 00279 return __write_integer(buf, 0, (long)((long)t->tm_year + 1900)); 00280 00281 case '%': 00282 *buf++ = '%'; 00283 return buf; 00284 00285 #if defined (__GNUC__) 00286 // fbp : at least on SUN 00287 # if defined (_STLP_UNIX) && !defined (__linux__) 00288 # define __USE_BSD 1 00289 # endif 00290 00291 /********************************************* 00292 * JGS, handle various extensions * 00293 *********************************************/ 00294 00295 case 'h': /* POSIX.2 extension */ 00296 // same as 'b', abbrev month name 00297 return copy(table._M_monthname[t->tm_mon].begin(), 00298 table._M_monthname[t->tm_mon].end(), 00299 buf); 00300 00301 case 'C': /* POSIX.2 extension */ 00302 // same as 'd', the day 00303 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_mday); 00304 return buf + 2; 00305 00306 case 'D': /* POSIX.2 extension */ 00307 // same as 'x' 00308 return __subformat(table._M_date_format, buf, buf_size, table, t); 00309 00310 case 'k': /* GNU extension */ 00311 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_hour); 00312 return buf + 2; 00313 00314 case 'l': /* GNU extension */ 00315 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_hour % 12); 00316 return buf + 2; 00317 00318 case 'n': /* POSIX.2 extension */ 00319 *buf++ = '\n'; 00320 return buf; 00321 00322 case 'R': /* GNU extension */ 00323 return __subformat("%H:%M", buf, buf_size, table, t); 00324 00325 case 'r': /* POSIX.2 extension */ 00326 return __subformat("%I:%M:%S %p", buf, buf_size, table, t); 00327 00328 case 'T': /* POSIX.2 extension. */ 00329 return __subformat("%H:%M:%S", buf, buf_size, table, t); 00330 00331 case 't': /* POSIX.2 extension. */ 00332 *buf++ = '\t'; 00333 return buf; 00334 00335 case 'u': /* POSIX.2 extension. */ 00336 return __write_integer(buf, 0, long((t->tm_wday - 1 + 7)) % 7 + 1); 00337 00338 case 's': { 00339 time_t __t; 00340 __t = mktime(__CONST_CAST(tm*, t)); 00341 return __write_integer(buf, 0, (long)__t ); 00342 } 00343 case 'g': /* GNU extension */ 00344 case 'G': { 00345 int year = t->tm_year + __TM_YEAR_BASE; 00346 int days = __iso_week_days (t->tm_yday, t->tm_wday); 00347 if (days < 0) { 00348 /* This ISO week belongs to the previous year. */ 00349 year--; 00350 days = __iso_week_days (t->tm_yday + (365 + __is_leap (year)), t->tm_wday); 00351 } 00352 else { 00353 int d = __iso_week_days (t->tm_yday - (365 + __is_leap (year)), t->tm_wday); 00354 if (0 <= d) { 00355 /* This ISO week belongs to the next year. */ 00356 ++year; 00357 days = d; 00358 } 00359 } 00360 switch (format) { 00361 case 'g': 00362 return __write_integer(buf, 0, (long)(year % 100 + 100) % 100); 00363 case 'G': 00364 return __write_integer(buf, 0, (long)year); 00365 default: 00366 return __write_integer(buf, 0, (long)days / 7 + 1); 00367 } 00368 } 00369 00370 # if defined (_STLP_USE_GLIBC) && ! defined (__CYGWIN__) 00371 case 'z': /* GNU extension. */ 00372 if (t->tm_isdst < 0) 00373 break; 00374 { 00375 int diff; 00376 # if defined (__USE_BSD) || defined (__BEOS__) 00377 diff = t->tm_gmtoff; 00378 # else 00379 diff = t->__tm_gmtoff; 00380 # endif 00381 if (diff < 0) { 00382 *buf++ = '-'; 00383 diff = -diff; 00384 } else 00385 *buf++ = '+'; 00386 diff /= 60; 00387 _STLP_SPRINTF(buf, buf_size, "%.4d", (diff / 60) * 100 + diff % 60); 00388 return buf + 4; 00389 } 00390 # endif /* __GLIBC__ */ 00391 #endif /* __GNUC__ */ 00392 00393 default: 00394 // return buf; 00395 break; 00396 } 00397 return buf; 00398 } 00399 00400 time_base::dateorder _STLP_CALL 00401 __get_date_order(_Locale_time* time) { 00402 const char * fmt = _Locale_d_fmt(time); 00403 char first, second, third; 00404 00405 while (*fmt != 0 && *fmt != '%') ++fmt; 00406 if (*fmt == 0) 00407 return time_base::no_order; 00408 first = *++fmt; 00409 while (*fmt != 0 && *fmt != '%') ++fmt; 00410 if (*fmt == 0) 00411 return time_base::no_order; 00412 second = *++fmt; 00413 while (*fmt != 0 && *fmt != '%') ++fmt; 00414 if (*fmt == 0) 00415 return time_base::no_order; 00416 third = *++fmt; 00417 00418 switch (first) { 00419 case 'd': 00420 return (second == 'm' && third == 'y') ? time_base::dmy 00421 : time_base::no_order; 00422 case 'm': 00423 return (second == 'd' && third == 'y') ? time_base::mdy 00424 : time_base::no_order; 00425 case 'y': 00426 switch (second) { 00427 case 'd': 00428 return third == 'm' ? time_base::ydm : time_base::no_order; 00429 case 'm': 00430 return third == 'd' ? time_base::ymd : time_base::no_order; 00431 default: 00432 return time_base::no_order; 00433 } 00434 default: 00435 return time_base::no_order; 00436 } 00437 } 00438 00439 _STLP_MOVE_TO_STD_NAMESPACE 00440 00441 #if !defined(_STLP_NO_FORCE_INSTANTIATE) 00442 template class time_get<char, istreambuf_iterator<char, char_traits<char> > >; 00443 template class time_put<char, ostreambuf_iterator<char, char_traits<char> > >; 00444 00445 # if !defined (_STLP_NO_WCHAR_T) 00446 template class time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >; 00447 template class time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >; 00448 # endif 00449 00450 #endif 00451 00452 _STLP_END_NAMESPACE
Generated on Mon Mar 10 15:32:17 2008 by ![]() |