Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentime_facets.cpp
Go 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 00025 #include "c_locale.h" 00026 #include "acquire_release.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 #ifndef _STLP_NO_WCHAR_T 00046 const wchar_t default_wdayname[][14] = { 00047 L"Sun", L"Mon", L"Tue", L"Wed", L"Thu", L"Fri", L"Sat", 00048 L"Sunday", L"Monday", L"Tuesday", L"Wednesday", L"Thursday", 00049 L"Friday", L"Saturday"}; 00050 00051 const wchar_t default_wmonthname[][24] = { 00052 L"Jan", L"Feb", L"Mar", L"Apr", L"May", L"Jun", 00053 L"Jul", L"Aug", L"Sep", L"Oct", L"Nov", L"Dec", 00054 L"January", L"February", L"March", L"April", L"May", L"June", 00055 L"July", L"August", L"September", L"October", L"November", L"December"}; 00056 #endif 00057 00058 #if defined (__BORLANDC__) 00059 _Time_Info time_init<char>::_M_timeinfo; 00060 # ifndef _STLP_NO_WCHAR_T 00061 _WTime_Info time_init<wchar_t>::_M_timeinfo; 00062 # endif 00063 #endif 00064 00065 // _Init_time_info: initialize table with 00066 // "C" values (note these are not defined in the C standard, so this 00067 // is somewhat arbitrary). 00068 00069 static void _Init_timeinfo_base(_Time_Info_Base& table) { 00070 table._M_time_format = "%H:%M:%S"; 00071 table._M_date_format = "%m/%d/%y"; 00072 table._M_date_time_format = "%m/%d/%y"; 00073 } 00074 00075 static void _Init_timeinfo(_Time_Info& table) { 00076 int i; 00077 for (i = 0; i < 14; ++i) 00078 table._M_dayname[i] = default_dayname[i]; 00079 for (i = 0; i < 24; ++i) 00080 table._M_monthname[i] = default_monthname[i]; 00081 table._M_am_pm[0] = "AM"; 00082 table._M_am_pm[1] = "PM"; 00083 _Init_timeinfo_base(table); 00084 } 00085 00086 #ifndef _STLP_NO_WCHAR_T 00087 static void _Init_timeinfo(_WTime_Info& table) { 00088 int i; 00089 for (i = 0; i < 14; ++i) 00090 table._M_dayname[i] = default_wdayname[i]; 00091 for (i = 0; i < 24; ++i) 00092 table._M_monthname[i] = default_wmonthname[i]; 00093 table._M_am_pm[0] = L"AM"; 00094 table._M_am_pm[1] = L"PM"; 00095 _Init_timeinfo_base(table); 00096 } 00097 #endif 00098 00099 static void _Init_timeinfo_base(_Time_Info_Base& table, _Locale_time * time) { 00100 table._M_time_format = _Locale_t_fmt(time); 00101 if ( table._M_time_format == "%T" ) { 00102 table._M_time_format = "%H:%M:%S"; 00103 } else if ( table._M_time_format == "%r" ) { 00104 table._M_time_format = "%I:%M:%S %p"; 00105 } else if ( table._M_time_format == "%R" ) { 00106 table._M_time_format = "%H:%M"; 00107 } 00108 table._M_date_format = _Locale_d_fmt(time); 00109 table._M_date_time_format = _Locale_d_t_fmt(time); 00110 table._M_long_date_format = _Locale_long_d_fmt(time); 00111 table._M_long_date_time_format = _Locale_long_d_t_fmt(time); 00112 } 00113 00114 static void _Init_timeinfo(_Time_Info& table, _Locale_time * time) { 00115 int i; 00116 for (i = 0; i < 7; ++i) 00117 table._M_dayname[i] = _Locale_abbrev_dayofweek(time, i); 00118 for (i = 0; i < 7; ++i) 00119 table._M_dayname[i+7] = _Locale_full_dayofweek(time, i); 00120 for (i = 0; i < 12; ++i) 00121 table._M_monthname[i] = _Locale_abbrev_monthname(time, i); 00122 for (i = 0; i < 12; ++i) 00123 table._M_monthname[i+12] = _Locale_full_monthname(time, i); 00124 table._M_am_pm[0] = _Locale_am_str(time); 00125 table._M_am_pm[1] = _Locale_pm_str(time); 00126 _Init_timeinfo_base(table, time); 00127 } 00128 00129 #ifndef _STLP_NO_WCHAR_T 00130 static void _Init_timeinfo(_WTime_Info& table, _Locale_time * time) { 00131 wchar_t buf[128]; 00132 int i; 00133 for (i = 0; i < 7; ++i) 00134 table._M_dayname[i] = _WLocale_abbrev_dayofweek(time, i, _STLP_ARRAY_AND_SIZE(buf)); 00135 for (i = 0; i < 7; ++i) 00136 table._M_dayname[i+7] = _WLocale_full_dayofweek(time, i, _STLP_ARRAY_AND_SIZE(buf)); 00137 for (i = 0; i < 12; ++i) 00138 table._M_monthname[i] = _WLocale_abbrev_monthname(time, i, _STLP_ARRAY_AND_SIZE(buf)); 00139 for (i = 0; i < 12; ++i) 00140 table._M_monthname[i+12] = _WLocale_full_monthname(time, i, _STLP_ARRAY_AND_SIZE(buf)); 00141 table._M_am_pm[0] = _WLocale_am_str(time, _STLP_ARRAY_AND_SIZE(buf)); 00142 table._M_am_pm[1] = _WLocale_pm_str(time, _STLP_ARRAY_AND_SIZE(buf)); 00143 _Init_timeinfo_base(table, time); 00144 } 00145 #endif 00146 00147 template <class _Ch, class _TimeInfo> 00148 void __subformat(_STLP_BASIC_IOSTRING(_Ch) &buf, const ctype<_Ch>& ct, 00149 const string& format, const _TimeInfo& table, const tm* t) { 00150 const char * cp = format.data(); 00151 const char * cp_end = cp + format.size(); 00152 while (cp != cp_end) { 00153 if (*cp == '%') { 00154 char mod = 0; 00155 ++cp; 00156 if (*cp == '#') { 00157 mod = *cp; ++cp; 00158 } 00159 __write_formatted_timeT(buf, ct, *cp++, mod, table, t); 00160 } else 00161 buf.append(1, *cp++); 00162 } 00163 } 00164 00165 static void __append(__iostring &buf, const string& name) 00166 { buf.append(name.data(), name.data() + name.size()); } 00167 00168 static void __append(__iowstring &buf, const wstring& name) 00169 { buf.append(name.data(), name.data() + name.size()); } 00170 00171 static void __append(__iostring &buf, char *first, char *last, const ctype<char>& /* ct */) 00172 { buf.append(first, last); } 00173 00174 static void __append(__iowstring &buf, char *first, char *last, const ctype<wchar_t>& ct) { 00175 wchar_t _wbuf[64]; 00176 ct.widen(first, last, _wbuf); 00177 buf.append(_wbuf, _wbuf + (last - first)); 00178 } 00179 00180 #if defined (__GNUC__) 00181 /* The number of days from the first day of the first ISO week of this 00182 year to the year day YDAY with week day WDAY. ISO weeks start on 00183 Monday; the first ISO week has the year's first Thursday. YDAY may 00184 be as small as YDAY_MINIMUM. */ 00185 # define __ISO_WEEK_START_WDAY 1 /* Monday */ 00186 # define __ISO_WEEK1_WDAY 4 /* Thursday */ 00187 # define __YDAY_MINIMUM (-366) 00188 # define __TM_YEAR_BASE 1900 00189 static int 00190 __iso_week_days(int yday, int wday) { 00191 /* Add enough to the first operand of % to make it nonnegative. */ 00192 int big_enough_multiple_of_7 = (-__YDAY_MINIMUM / 7 + 2) * 7; 00193 return (yday 00194 - (yday - wday + __ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 00195 + __ISO_WEEK1_WDAY - __ISO_WEEK_START_WDAY); 00196 } 00197 00198 # define __is_leap(year)\ 00199 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) 00200 00201 #endif 00202 00203 #define __hour12(hour) \ 00204 (((hour) % 12 == 0) ? (12) : (hour) % 12) 00205 00206 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS) 00207 # define _STLP_SPRINTF sprintf 00208 #else 00209 # define _STLP_SPRINTF sprintf_s 00210 #endif 00211 00212 template <class _Ch, class _TimeInfo> 00213 void _STLP_CALL __write_formatted_timeT(_STLP_BASIC_IOSTRING(_Ch) &buf, 00214 const ctype<_Ch>& ct, 00215 char format, char modifier, 00216 const _TimeInfo& table, const tm* t) { 00217 char _buf[64]; 00218 char *_bend; 00219 00220 switch (format) { 00221 case 'a': 00222 __append(buf, table._M_dayname[t->tm_wday]); 00223 break; 00224 00225 case 'A': 00226 __append(buf, table._M_dayname[t->tm_wday + 7]); 00227 break; 00228 00229 case 'b': 00230 __append(buf, table._M_monthname[t->tm_mon]); 00231 break; 00232 00233 case 'B': 00234 __append(buf, table._M_monthname[t->tm_mon + 12]); 00235 break; 00236 00237 case 'c': 00238 __subformat(buf, ct, (modifier != '#') ? table._M_date_time_format 00239 : table._M_long_date_time_format, table, t); 00240 break; 00241 00242 case 'd': 00243 _STLP_SPRINTF(_buf, (modifier != '#') ? "%.2ld" : "%ld", (long)t->tm_mday); 00244 __append(buf, _buf, ((long)t->tm_mday < 10L && modifier == '#') ? _buf + 1 : _buf + 2, ct); 00245 break; 00246 00247 case 'e': 00248 _STLP_SPRINTF(_buf, "%2ld", (long)t->tm_mday); 00249 __append(buf, _buf, _buf + 2, ct); 00250 break; 00251 00252 case 'H': 00253 _STLP_SPRINTF(_buf, (modifier != '#') ? "%.2ld" : "%ld", (long)t->tm_hour); 00254 __append(buf, _buf, ((long)t->tm_hour < 10L && modifier == '#') ? _buf + 1 : _buf + 2, ct); 00255 break; 00256 00257 case 'I': 00258 _STLP_SPRINTF(_buf, (modifier != '#') ? "%.2ld" : "%ld", (long)__hour12(t->tm_hour)); 00259 __append(buf, _buf, ((long)__hour12(t->tm_hour) < 10L && modifier == '#') ? _buf + 1 : _buf + 2, ct); 00260 break; 00261 00262 case 'j': 00263 _bend = __write_integer(_buf, 0, (long)((long)t->tm_yday + 1)); 00264 __append(buf, _buf, _bend, ct); 00265 break; 00266 00267 case 'm': 00268 _STLP_SPRINTF(_buf, (modifier != '#') ? "%.2ld" : "%ld", (long)t->tm_mon + 1); 00269 __append(buf, _buf, ((long)(t->tm_mon + 1) < 10L && modifier == '#') ? _buf + 1 : _buf + 2, ct); 00270 break; 00271 00272 case 'M': 00273 _STLP_SPRINTF(_buf, (modifier != '#') ? "%.2ld" : "%ld", (long)t->tm_min); 00274 __append(buf, _buf, ((long)t->tm_min < 10L && modifier == '#') ? _buf + 1 : _buf + 2, ct); 00275 break; 00276 00277 case 'p': 00278 __append(buf, table._M_am_pm[t->tm_hour / 12]); 00279 break; 00280 00281 case 'S': // pad with zeros 00282 _STLP_SPRINTF(_buf, (modifier != '#') ? "%.2ld" : "%ld", (long)t->tm_sec); 00283 __append(buf, _buf, ((long)t->tm_sec < 10L && modifier == '#') ? _buf + 1 : _buf + 2, ct); 00284 break; 00285 00286 case 'U': 00287 _bend = __write_integer(_buf, 0, long((t->tm_yday - t->tm_wday + 7) / 7)); 00288 __append(buf, _buf, _bend, ct); 00289 break; 00290 00291 case 'w': 00292 _bend = __write_integer(_buf, 0, (long)t->tm_wday); 00293 __append(buf, _buf, _bend, ct); 00294 break; 00295 00296 case 'W': 00297 _bend = __write_integer(_buf, 0, 00298 (long)(t->tm_wday == 0 ? (t->tm_yday + 1) / 7 : 00299 (t->tm_yday + 8 - t->tm_wday) / 7)); 00300 __append(buf, _buf, _bend, ct); 00301 break; 00302 00303 case'x': 00304 __subformat(buf, ct, (modifier != '#') ? table._M_date_format 00305 : table._M_long_date_format, table, t); 00306 break; 00307 00308 case 'X': 00309 __subformat(buf, ct, table._M_time_format, table, t); 00310 break; 00311 00312 case 'y': 00313 _bend = __write_integer(_buf, 0, (long)((long)(t->tm_year + 1900) % 100)); 00314 __append(buf, _buf, _bend, ct); 00315 break; 00316 00317 case 'Y': 00318 _bend = __write_integer(_buf, 0, (long)((long)t->tm_year + 1900)); 00319 __append(buf, _buf, _bend, ct); 00320 break; 00321 00322 case '%': 00323 buf.append(1, ct.widen('%')); 00324 break; 00325 00326 #if defined (__GNUC__) 00327 // fbp : at least on SUN 00328 # if defined (_STLP_UNIX) && !defined (__linux__) 00329 # define __USE_BSD 1 00330 # endif 00331 00332 /********************************************* 00333 * JGS, handle various extensions * 00334 *********************************************/ 00335 00336 case 'h': /* POSIX.2 extension */ 00337 // same as 'b', abbrev month name 00338 __append(buf, table._M_monthname[t->tm_mon]); 00339 break; 00340 case 'C': /* POSIX.2 extension */ 00341 // same as 'd', the day 00342 _STLP_SPRINTF(_buf, "%2ld", (long)t->tm_mday); 00343 __append(buf, _buf, _buf + 2, ct); 00344 break; 00345 00346 case 'D': /* POSIX.2 extension */ 00347 // same as 'x' 00348 __subformat(buf, ct, table._M_date_format, table, t); 00349 break; 00350 00351 case 'k': /* GNU extension */ 00352 _STLP_SPRINTF(_buf, "%2ld", (long)t->tm_hour); 00353 __append(buf, _buf, _buf + 2, ct); 00354 break; 00355 00356 case 'l': /* GNU extension */ 00357 _STLP_SPRINTF(_buf, "%2ld", (long)t->tm_hour % 12); 00358 __append(buf, _buf, _buf + 2, ct); 00359 break; 00360 00361 case 'n': /* POSIX.2 extension */ 00362 buf.append(1, ct.widen('\n')); 00363 break; 00364 00365 case 'R': /* GNU extension */ 00366 __subformat(buf, ct, "%H:%M", table, t); 00367 break; 00368 00369 case 'r': /* POSIX.2 extension */ 00370 __subformat(buf, ct, "%I:%M:%S %p", table, t); 00371 break; 00372 00373 case 'T': /* POSIX.2 extension. */ 00374 __subformat(buf, ct, "%H:%M:%S", table, t); 00375 break; 00376 00377 case 't': /* POSIX.2 extension. */ 00378 buf.append(1, ct.widen('\t')); 00379 00380 case 'u': /* POSIX.2 extension. */ 00381 _bend = __write_integer(_buf, 0, long((t->tm_wday - 1 + 7)) % 7 + 1); 00382 __append(buf, _buf, _bend, ct); 00383 break; 00384 00385 case 's': { 00386 time_t __t = mktime(__CONST_CAST(tm*, t)); 00387 _bend = __write_integer(_buf, 0, (long)__t ); 00388 __append(buf, _buf, _bend, ct); 00389 break; 00390 } 00391 case 'g': /* GNU extension */ 00392 case 'G': { 00393 int year = t->tm_year + __TM_YEAR_BASE; 00394 int days = __iso_week_days (t->tm_yday, t->tm_wday); 00395 if (days < 0) { 00396 /* This ISO week belongs to the previous year. */ 00397 year--; 00398 days = __iso_week_days (t->tm_yday + (365 + __is_leap (year)), t->tm_wday); 00399 } 00400 else { 00401 int d = __iso_week_days (t->tm_yday - (365 + __is_leap (year)), t->tm_wday); 00402 if (0 <= d) { 00403 /* This ISO week belongs to the next year. */ 00404 ++year; 00405 days = d; 00406 } 00407 } 00408 long val; 00409 switch (format) { 00410 case 'g': 00411 val = (long)(year % 100 + 100) % 100; 00412 break; 00413 case 'G': 00414 val = (long)year; 00415 break; 00416 default: 00417 val = (long)days / 7 + 1; 00418 break; 00419 } 00420 _bend = __write_integer(_buf, 0, val); 00421 __append(buf, _buf, _bend, ct); 00422 break; 00423 } 00424 00425 # if defined (_STLP_USE_GLIBC) 00426 case 'z': /* GNU extension. */ 00427 if (t->tm_isdst < 0) 00428 break; 00429 { 00430 int diff; 00431 # if defined (__USE_BSD) || defined (__BEOS__) 00432 diff = t->tm_gmtoff; 00433 # else 00434 diff = t->__tm_gmtoff; 00435 # endif 00436 if (diff < 0) { 00437 buf.append(1, ct.widen('-')); 00438 diff = -diff; 00439 } else 00440 buf.append(1, ct.widen('+')); 00441 diff /= 60; 00442 _STLP_SPRINTF(_buf, "%.4d", (diff / 60) * 100 + diff % 60); 00443 __append(buf, _buf, _buf + 4, ct); 00444 break; 00445 } 00446 # endif /* __GLIBC__ */ 00447 #endif /* __GNUC__ */ 00448 00449 default: 00450 break; 00451 } 00452 } 00453 00454 void _STLP_CALL __write_formatted_time(__iostring &buf, const ctype<char>& ct, 00455 char format, char modifier, 00456 const _Time_Info& table, const tm* t) 00457 { __write_formatted_timeT(buf, ct, format, modifier, table, t); } 00458 00459 void _STLP_CALL __write_formatted_time(__iowstring &buf, const ctype<wchar_t>& ct, 00460 char format, char modifier, 00461 const _WTime_Info& table, const tm* t) 00462 { __write_formatted_timeT(buf, ct, format, modifier, table, t); } 00463 00464 static time_base::dateorder __get_date_order(_Locale_time* time) { 00465 const char * fmt = _Locale_d_fmt(time); 00466 char first, second, third; 00467 00468 while (*fmt != 0 && *fmt != '%') ++fmt; 00469 if (*fmt == 0) 00470 return time_base::no_order; 00471 first = *++fmt; 00472 while (*fmt != 0 && *fmt != '%') ++fmt; 00473 if (*fmt == 0) 00474 return time_base::no_order; 00475 second = *++fmt; 00476 while (*fmt != 0 && *fmt != '%') ++fmt; 00477 if (*fmt == 0) 00478 return time_base::no_order; 00479 third = *++fmt; 00480 00481 switch (first) { 00482 case 'd': 00483 return (second == 'm' && third == 'y') ? time_base::dmy 00484 : time_base::no_order; 00485 case 'm': 00486 return (second == 'd' && third == 'y') ? time_base::mdy 00487 : time_base::no_order; 00488 case 'y': 00489 switch (second) { 00490 case 'd': 00491 return third == 'm' ? time_base::ydm : time_base::no_order; 00492 case 'm': 00493 return third == 'd' ? time_base::ymd : time_base::no_order; 00494 default: 00495 return time_base::no_order; 00496 } 00497 default: 00498 return time_base::no_order; 00499 } 00500 } 00501 00502 time_init<char>::time_init() 00503 : _M_dateorder(time_base::no_order) 00504 { _Init_timeinfo(_M_timeinfo); } 00505 00506 time_init<char>::time_init(const char* __name) { 00507 if (!__name) 00508 locale::_M_throw_on_null_name(); 00509 00510 int __err_code; 00511 char buf[_Locale_MAX_SIMPLE_NAME]; 00512 _Locale_time *__time = __acquire_time(__name, buf, 0, &__err_code); 00513 if (!__time) 00514 locale::_M_throw_on_creation_failure(__err_code, __name, "time"); 00515 00516 _Init_timeinfo(this->_M_timeinfo, __time); 00517 _M_dateorder = __get_date_order(__time); 00518 __release_time(__time); 00519 } 00520 00521 time_init<char>::time_init(_Locale_time *__time) { 00522 _Init_timeinfo(this->_M_timeinfo, __time); 00523 _M_dateorder = __get_date_order(__time); 00524 } 00525 00526 #ifndef _STLP_NO_WCHAR_T 00527 time_init<wchar_t>::time_init() 00528 : _M_dateorder(time_base::no_order) 00529 { _Init_timeinfo(_M_timeinfo); } 00530 00531 time_init<wchar_t>::time_init(const char* __name) { 00532 if (!__name) 00533 locale::_M_throw_on_null_name(); 00534 00535 int __err_code; 00536 char buf[_Locale_MAX_SIMPLE_NAME]; 00537 _Locale_time *__time = __acquire_time(__name, buf, 0, &__err_code); 00538 if (!__time) 00539 locale::_M_throw_on_creation_failure(__err_code, __name, "time"); 00540 00541 _Init_timeinfo(this->_M_timeinfo, __time); 00542 _M_dateorder = __get_date_order(__time); 00543 __release_time(__time); 00544 } 00545 00546 time_init<wchar_t>::time_init(_Locale_time *__time) { 00547 _Init_timeinfo(this->_M_timeinfo, __time); 00548 _M_dateorder = __get_date_order(__time); 00549 } 00550 #endif 00551 00552 _STLP_MOVE_TO_STD_NAMESPACE 00553 00554 #if !defined (_STLP_NO_FORCE_INSTANTIATE) 00555 template class time_get<char, istreambuf_iterator<char, char_traits<char> > >; 00556 template class time_put<char, ostreambuf_iterator<char, char_traits<char> > >; 00557 00558 # ifndef _STLP_NO_WCHAR_T 00559 template class time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >; 00560 template class time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >; 00561 # endif 00562 00563 #endif 00564 00565 _STLP_END_NAMESPACE Generated on Sun May 27 2012 04:35:14 for ReactOS by
1.7.6.1
|