3 * Silicon Graphics Computer Systems, Inc.
8 * This material is provided "as is", with absolutely no warranty expressed
9 * or implied. Any use is at your own risk.
11 * Permission to use or copy this software for any purpose is hereby granted
12 * without fee, provided the above notices are retained on all copies.
13 * Permission to modify the code and to distribute modified code is granted,
14 * provided the above notices are retained, and a notice that the code was
15 * modified is included with the above copyright notice.
19 #include "stlport_prefix.h"
30 _STLP_MOVE_TO_PRIV_NAMESPACE
32 // default "C" values for month and day names
34 const char default_dayname[][14] = {
35 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
36 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
37 "Friday", "Saturday"};
39 const char default_monthname[][24] = {
40 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
41 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
42 "January", "February", "March", "April", "May", "June",
43 "July", "August", "September", "October", "November", "December"};
45 // _Init_time_info: initialize table with
46 // "C" values (note these are not defined in the C standard, so this
47 // is somewhat arbitrary).
49 void _STLP_CALL _Init_timeinfo(_Time_Info& table) {
51 for (i = 0; i < 14; ++i)
52 table._M_dayname[i] = default_dayname[i];
53 for (i = 0; i < 24; ++i)
54 table._M_monthname[i] = default_monthname[i];
55 table._M_am_pm[0] = "AM";
56 table._M_am_pm[1] = "PM";
57 table._M_time_format = "%H:%M:%S";
58 table._M_date_format = "%m/%d/%y";
59 table._M_date_time_format = "%m/%d/%y";
62 void _STLP_CALL _Init_timeinfo(_Time_Info& table, _Locale_time * time) {
64 locale::_M_throw_runtime_error();
67 for (i = 0; i < 7; ++i)
68 table._M_dayname[i] = _Locale_abbrev_dayofweek(time, i);
69 for (i = 0; i < 7; ++i)
70 table._M_dayname[i+7] = _Locale_full_dayofweek(time, i);
71 for (i = 0; i < 12; ++i)
72 table._M_monthname[i] = _Locale_abbrev_monthname(time, i);
73 for (i = 0; i < 12; ++i)
74 table._M_monthname[i+12] = _Locale_full_monthname(time, i);
75 table._M_am_pm[0] = _Locale_am_str(time);
76 table._M_am_pm[1] = _Locale_pm_str(time);
77 table._M_time_format = _Locale_t_fmt(time);
78 if ( table._M_time_format == "%T" ) {
79 table._M_time_format = "%H:%M:%S";
80 } else if ( table._M_time_format == "%r" ) {
81 table._M_time_format = "%I:%M:%S %p";
82 } else if ( table._M_time_format == "%R" ) {
83 table._M_time_format = "%H:%M";
85 table._M_date_format = _Locale_d_fmt(time);
86 table._M_date_time_format = _Locale_d_t_fmt(time);
87 table._M_long_date_format = _Locale_long_d_fmt(time);
88 table._M_long_date_time_format = _Locale_long_d_t_fmt(time);
91 inline char* __subformat(const string& format, char*& buf, size_t buf_size,
92 const _Time_Info& table, const tm* t) {
93 const char * cp = format.data();
94 const char * cp_end = cp + format.size();
95 while (cp != cp_end) {
102 char *former_buf = buf;
103 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
104 buf_size -= (buf - former_buf);
111 #if defined (__GNUC__)
112 /* The number of days from the first day of the first ISO week of this
113 year to the year day YDAY with week day WDAY. ISO weeks start on
114 Monday; the first ISO week has the year's first Thursday. YDAY may
115 be as small as YDAY_MINIMUM. */
116 # define __ISO_WEEK_START_WDAY 1 /* Monday */
117 # define __ISO_WEEK1_WDAY 4 /* Thursday */
118 # define __YDAY_MINIMUM (-366)
119 # define __TM_YEAR_BASE 1900
121 __iso_week_days(int yday, int wday) {
122 /* Add enough to the first operand of % to make it nonnegative. */
123 int big_enough_multiple_of_7 = (-__YDAY_MINIMUM / 7 + 2) * 7;
125 - (yday - wday + __ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
126 + __ISO_WEEK1_WDAY - __ISO_WEEK_START_WDAY);
129 # define __is_leap(year)\
130 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
134 #define __hour12(hour) \
135 (((hour) % 12 == 0) ? (12) : (hour) % 12)
137 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
138 # define _STLP_SPRINTF(B, BS, F, D) sprintf(B, F, D)
140 # define _STLP_SPRINTF(B, BS, F, D) sprintf_s(B, BS, F, D)
143 char * _STLP_CALL __write_formatted_time(char* buf, size_t buf_size, char format, char modifier,
144 const _Time_Info& table, const tm* t) {
147 return copy(table._M_dayname[t->tm_wday].begin(),
148 table._M_dayname[t->tm_wday].end(),
152 return copy(table._M_dayname[t->tm_wday+7].begin(),
153 table._M_dayname[t->tm_wday+7].end(),
157 return copy(table._M_monthname[t->tm_mon].begin(),
158 table._M_monthname[t->tm_mon].end(),
162 return copy(table._M_monthname[t->tm_mon+12].begin(),
163 table._M_monthname[t->tm_mon+12].end(),
167 const char *cp = (modifier != '#') ?
168 table._M_date_time_format.data() :
169 table._M_long_date_time_format.data();
170 const char* cp_end = cp +
171 ((modifier != '#') ? table._M_date_time_format.size() :
172 table._M_long_date_time_format.size() );
174 while (cp != cp_end) {
176 ++cp; if(*cp == '#') mod = *cp++; else mod = 0;
178 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
179 buf_size -= (buf - buf_pos);
182 *buf++ = *cp++; --buf_size;
189 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_mday);
190 return ((long)t->tm_mday < 10L && modifier == '#')?buf+1:buf + 2;
193 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_mday);
197 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_hour);
198 return ((long)t->tm_hour < 10L && modifier == '#')?buf+1:buf + 2;
201 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)__hour12(t->tm_hour));
202 return ((long)__hour12(t->tm_hour) < 10L && modifier == '#')?buf+1:buf + 2;
205 return __write_integer(buf, 0, (long)((long)t->tm_yday + 1));
208 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_mon + 1);
209 return ((long)(t->tm_mon + 1) < 10L && modifier == '#')?buf+1:buf + 2;
212 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_min);
213 return ((long)t->tm_min < 10L && modifier == '#')?buf+1:buf + 2;
216 return copy(table._M_am_pm[t->tm_hour/12].begin(),
217 table._M_am_pm[t->tm_hour/12].end(),
220 case 'S': // pad with zeros
221 _STLP_SPRINTF(buf, buf_size, (modifier != '#')?"%.2ld":"%ld", (long)t->tm_sec);
222 return ((long)t->tm_sec < 10L && modifier == '#')?buf+1:buf + 2;
225 return __write_integer(buf, 0,
226 long((t->tm_yday - t->tm_wday + 7) / 7));
230 return __write_integer(buf, 0, (long)t->tm_wday);
234 return __write_integer(buf, 0,
235 (long)(t->tm_wday == 0 ? (t->tm_yday + 1) / 7 :
236 (t->tm_yday + 8 - t->tm_wday) / 7));
239 const char * cp = (modifier != '#') ? table._M_date_format.data():
240 table._M_long_date_format.data();
241 const char* cp_end = (modifier != '#') ? cp + table._M_date_format.size():
242 cp + table._M_long_date_format.size();
244 while (cp != cp_end) {
246 ++cp; if(*cp == '#') mod = *cp++; else mod = 0;
248 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
249 buf_size -= (buf - buf_pos);
252 *buf++ = *cp++; --buf_size;
259 const char * cp = table._M_time_format.data();
260 const char* cp_end = cp + table._M_time_format.size();
262 while (cp != cp_end) {
264 ++cp; if(*cp == '#') mod = *cp++; else mod = 0;
266 buf = __write_formatted_time(buf, buf_size, *cp++, mod, table, t);
267 buf_size -= (buf - buf_pos);
270 *buf++ = *cp++; --buf_size;
276 return __write_integer(buf, 0, (long)((long)(t->tm_year + 1900) % 100));
279 return __write_integer(buf, 0, (long)((long)t->tm_year + 1900));
285 #if defined (__GNUC__)
286 // fbp : at least on SUN
287 # if defined (_STLP_UNIX) && !defined (__linux__)
291 /*********************************************
292 * JGS, handle various extensions *
293 *********************************************/
295 case 'h': /* POSIX.2 extension */
296 // same as 'b', abbrev month name
297 return copy(table._M_monthname[t->tm_mon].begin(),
298 table._M_monthname[t->tm_mon].end(),
301 case 'C': /* POSIX.2 extension */
302 // same as 'd', the day
303 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_mday);
306 case 'D': /* POSIX.2 extension */
308 return __subformat(table._M_date_format, buf, buf_size, table, t);
310 case 'k': /* GNU extension */
311 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_hour);
314 case 'l': /* GNU extension */
315 _STLP_SPRINTF(buf, buf_size, "%2ld", (long)t->tm_hour % 12);
318 case 'n': /* POSIX.2 extension */
322 case 'R': /* GNU extension */
323 return __subformat("%H:%M", buf, buf_size, table, t);
325 case 'r': /* POSIX.2 extension */
326 return __subformat("%I:%M:%S %p", buf, buf_size, table, t);
328 case 'T': /* POSIX.2 extension. */
329 return __subformat("%H:%M:%S", buf, buf_size, table, t);
331 case 't': /* POSIX.2 extension. */
335 case 'u': /* POSIX.2 extension. */
336 return __write_integer(buf, 0, long((t->tm_wday - 1 + 7)) % 7 + 1);
340 __t = mktime(__CONST_CAST(tm*, t));
341 return __write_integer(buf, 0, (long)__t );
343 case 'g': /* GNU extension */
345 int year = t->tm_year + __TM_YEAR_BASE;
346 int days = __iso_week_days (t->tm_yday, t->tm_wday);
348 /* This ISO week belongs to the previous year. */
350 days = __iso_week_days (t->tm_yday + (365 + __is_leap (year)), t->tm_wday);
353 int d = __iso_week_days (t->tm_yday - (365 + __is_leap (year)), t->tm_wday);
355 /* This ISO week belongs to the next year. */
362 return __write_integer(buf, 0, (long)(year % 100 + 100) % 100);
364 return __write_integer(buf, 0, (long)year);
366 return __write_integer(buf, 0, (long)days / 7 + 1);
370 # if defined (_STLP_USE_GLIBC) && ! defined (__CYGWIN__)
371 case 'z': /* GNU extension. */
376 # if defined (__USE_BSD) || defined (__BEOS__)
379 diff = t->__tm_gmtoff;
387 _STLP_SPRINTF(buf, buf_size, "%.4d", (diff / 60) * 100 + diff % 60);
390 # endif /* __GLIBC__ */
391 #endif /* __GNUC__ */
400 time_base::dateorder _STLP_CALL
401 __get_date_order(_Locale_time* time) {
402 const char * fmt = _Locale_d_fmt(time);
403 char first, second, third;
405 while (*fmt != 0 && *fmt != '%') ++fmt;
407 return time_base::no_order;
409 while (*fmt != 0 && *fmt != '%') ++fmt;
411 return time_base::no_order;
413 while (*fmt != 0 && *fmt != '%') ++fmt;
415 return time_base::no_order;
420 return (second == 'm' && third == 'y') ? time_base::dmy
421 : time_base::no_order;
423 return (second == 'd' && third == 'y') ? time_base::mdy
424 : time_base::no_order;
428 return third == 'm' ? time_base::ydm : time_base::no_order;
430 return third == 'd' ? time_base::ymd : time_base::no_order;
432 return time_base::no_order;
435 return time_base::no_order;
439 _STLP_MOVE_TO_STD_NAMESPACE
441 #if !defined(_STLP_NO_FORCE_INSTANTIATE)
442 template class time_get<char, istreambuf_iterator<char, char_traits<char> > >;
443 template class time_put<char, ostreambuf_iterator<char, char_traits<char> > >;
445 # if !defined (_STLP_NO_WCHAR_T)
446 template class time_get<wchar_t, istreambuf_iterator<wchar_t, char_traits<wchar_t> > >;
447 template class time_put<wchar_t, ostreambuf_iterator<wchar_t, char_traits<wchar_t> > >;