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"
26 #include "acquire_release.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 #ifndef _STLP_NO_WCHAR_T
46 const wchar_t default_wdayname
[][14] = {
47 L
"Sun", L
"Mon", L
"Tue", L
"Wed", L
"Thu", L
"Fri", L
"Sat",
48 L
"Sunday", L
"Monday", L
"Tuesday", L
"Wednesday", L
"Thursday",
49 L
"Friday", L
"Saturday"};
51 const wchar_t default_wmonthname
[][24] = {
52 L
"Jan", L
"Feb", L
"Mar", L
"Apr", L
"May", L
"Jun",
53 L
"Jul", L
"Aug", L
"Sep", L
"Oct", L
"Nov", L
"Dec",
54 L
"January", L
"February", L
"March", L
"April", L
"May", L
"June",
55 L
"July", L
"August", L
"September", L
"October", L
"November", L
"December"};
58 #if defined (__BORLANDC__)
59 _Time_Info time_init
<char>::_M_timeinfo
;
60 # ifndef _STLP_NO_WCHAR_T
61 _WTime_Info time_init
<wchar_t>::_M_timeinfo
;
65 // _Init_time_info: initialize table with
66 // "C" values (note these are not defined in the C standard, so this
67 // is somewhat arbitrary).
69 static void _Init_timeinfo_base(_Time_Info_Base
& table
) {
70 table
._M_time_format
= "%H:%M:%S";
71 table
._M_date_format
= "%m/%d/%y";
72 table
._M_date_time_format
= "%m/%d/%y";
75 static void _Init_timeinfo(_Time_Info
& table
) {
77 for (i
= 0; i
< 14; ++i
)
78 table
._M_dayname
[i
] = default_dayname
[i
];
79 for (i
= 0; i
< 24; ++i
)
80 table
._M_monthname
[i
] = default_monthname
[i
];
81 table
._M_am_pm
[0] = "AM";
82 table
._M_am_pm
[1] = "PM";
83 _Init_timeinfo_base(table
);
86 #ifndef _STLP_NO_WCHAR_T
87 static void _Init_timeinfo(_WTime_Info
& table
) {
89 for (i
= 0; i
< 14; ++i
)
90 table
._M_dayname
[i
] = default_wdayname
[i
];
91 for (i
= 0; i
< 24; ++i
)
92 table
._M_monthname
[i
] = default_wmonthname
[i
];
93 table
._M_am_pm
[0] = L
"AM";
94 table
._M_am_pm
[1] = L
"PM";
95 _Init_timeinfo_base(table
);
99 static void _Init_timeinfo_base(_Time_Info_Base
& table
, _Locale_time
* time
) {
100 table
._M_time_format
= _Locale_t_fmt(time
);
101 if ( table
._M_time_format
== "%T" ) {
102 table
._M_time_format
= "%H:%M:%S";
103 } else if ( table
._M_time_format
== "%r" ) {
104 table
._M_time_format
= "%I:%M:%S %p";
105 } else if ( table
._M_time_format
== "%R" ) {
106 table
._M_time_format
= "%H:%M";
108 table
._M_date_format
= _Locale_d_fmt(time
);
109 table
._M_date_time_format
= _Locale_d_t_fmt(time
);
110 table
._M_long_date_format
= _Locale_long_d_fmt(time
);
111 table
._M_long_date_time_format
= _Locale_long_d_t_fmt(time
);
114 static void _Init_timeinfo(_Time_Info
& table
, _Locale_time
* time
) {
116 for (i
= 0; i
< 7; ++i
)
117 table
._M_dayname
[i
] = _Locale_abbrev_dayofweek(time
, i
);
118 for (i
= 0; i
< 7; ++i
)
119 table
._M_dayname
[i
+7] = _Locale_full_dayofweek(time
, i
);
120 for (i
= 0; i
< 12; ++i
)
121 table
._M_monthname
[i
] = _Locale_abbrev_monthname(time
, i
);
122 for (i
= 0; i
< 12; ++i
)
123 table
._M_monthname
[i
+12] = _Locale_full_monthname(time
, i
);
124 table
._M_am_pm
[0] = _Locale_am_str(time
);
125 table
._M_am_pm
[1] = _Locale_pm_str(time
);
126 _Init_timeinfo_base(table
, time
);
129 #ifndef _STLP_NO_WCHAR_T
130 static void _Init_timeinfo(_WTime_Info
& table
, _Locale_time
* time
) {
133 for (i
= 0; i
< 7; ++i
)
134 table
._M_dayname
[i
] = _WLocale_abbrev_dayofweek(time
, i
, _STLP_ARRAY_AND_SIZE(buf
));
135 for (i
= 0; i
< 7; ++i
)
136 table
._M_dayname
[i
+7] = _WLocale_full_dayofweek(time
, i
, _STLP_ARRAY_AND_SIZE(buf
));
137 for (i
= 0; i
< 12; ++i
)
138 table
._M_monthname
[i
] = _WLocale_abbrev_monthname(time
, i
, _STLP_ARRAY_AND_SIZE(buf
));
139 for (i
= 0; i
< 12; ++i
)
140 table
._M_monthname
[i
+12] = _WLocale_full_monthname(time
, i
, _STLP_ARRAY_AND_SIZE(buf
));
141 table
._M_am_pm
[0] = _WLocale_am_str(time
, _STLP_ARRAY_AND_SIZE(buf
));
142 table
._M_am_pm
[1] = _WLocale_pm_str(time
, _STLP_ARRAY_AND_SIZE(buf
));
143 _Init_timeinfo_base(table
, time
);
147 template <class _Ch
, class _TimeInfo
>
148 void __subformat(_STLP_BASIC_IOSTRING(_Ch
) &buf
, const ctype
<_Ch
>& ct
,
149 const string
& format
, const _TimeInfo
& table
, const tm
* t
) {
150 const char * cp
= format
.data();
151 const char * cp_end
= cp
+ format
.size();
152 while (cp
!= cp_end
) {
159 __write_formatted_timeT(buf
, ct
, *cp
++, mod
, table
, t
);
161 buf
.append(1, *cp
++);
165 static void __append(__iostring
&buf
, const string
& name
)
166 { buf
.append(name
.data(), name
.data() + name
.size()); }
168 static void __append(__iowstring
&buf
, const wstring
& name
)
169 { buf
.append(name
.data(), name
.data() + name
.size()); }
171 static void __append(__iostring
&buf
, char *first
, char *last
, const ctype
<char>& /* ct */)
172 { buf
.append(first
, last
); }
174 static void __append(__iowstring
&buf
, char *first
, char *last
, const ctype
<wchar_t>& ct
) {
176 ct
.widen(first
, last
, _wbuf
);
177 buf
.append(_wbuf
, _wbuf
+ (last
- first
));
180 #if defined (__GNUC__)
181 /* The number of days from the first day of the first ISO week of this
182 year to the year day YDAY with week day WDAY. ISO weeks start on
183 Monday; the first ISO week has the year's first Thursday. YDAY may
184 be as small as YDAY_MINIMUM. */
185 # define __ISO_WEEK_START_WDAY 1 /* Monday */
186 # define __ISO_WEEK1_WDAY 4 /* Thursday */
187 # define __YDAY_MINIMUM (-366)
188 # define __TM_YEAR_BASE 1900
190 __iso_week_days(int yday
, int wday
) {
191 /* Add enough to the first operand of % to make it nonnegative. */
192 int big_enough_multiple_of_7
= (-__YDAY_MINIMUM
/ 7 + 2) * 7;
194 - (yday
- wday
+ __ISO_WEEK1_WDAY
+ big_enough_multiple_of_7
) % 7
195 + __ISO_WEEK1_WDAY
- __ISO_WEEK_START_WDAY
);
198 # define __is_leap(year)\
199 ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
203 #define __hour12(hour) \
204 (((hour) % 12 == 0) ? (12) : (hour) % 12)
206 #if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
207 # define _STLP_SPRINTF sprintf
209 # define _STLP_SPRINTF sprintf_s
212 template <class _Ch
, class _TimeInfo
>
213 void _STLP_CALL
__write_formatted_timeT(_STLP_BASIC_IOSTRING(_Ch
) &buf
,
214 const ctype
<_Ch
>& ct
,
215 char format
, char modifier
,
216 const _TimeInfo
& table
, const tm
* t
) {
222 __append(buf
, table
._M_dayname
[t
->tm_wday
]);
226 __append(buf
, table
._M_dayname
[t
->tm_wday
+ 7]);
230 __append(buf
, table
._M_monthname
[t
->tm_mon
]);
234 __append(buf
, table
._M_monthname
[t
->tm_mon
+ 12]);
238 __subformat(buf
, ct
, (modifier
!= '#') ? table
._M_date_time_format
239 : table
._M_long_date_time_format
, table
, t
);
243 _STLP_SPRINTF(_buf
, (modifier
!= '#') ? "%.2ld" : "%ld", (long)t
->tm_mday
);
244 __append(buf
, _buf
, ((long)t
->tm_mday
< 10L && modifier
== '#') ? _buf
+ 1 : _buf
+ 2, ct
);
248 _STLP_SPRINTF(_buf
, "%2ld", (long)t
->tm_mday
);
249 __append(buf
, _buf
, _buf
+ 2, ct
);
253 _STLP_SPRINTF(_buf
, (modifier
!= '#') ? "%.2ld" : "%ld", (long)t
->tm_hour
);
254 __append(buf
, _buf
, ((long)t
->tm_hour
< 10L && modifier
== '#') ? _buf
+ 1 : _buf
+ 2, ct
);
258 _STLP_SPRINTF(_buf
, (modifier
!= '#') ? "%.2ld" : "%ld", (long)__hour12(t
->tm_hour
));
259 __append(buf
, _buf
, ((long)__hour12(t
->tm_hour
) < 10L && modifier
== '#') ? _buf
+ 1 : _buf
+ 2, ct
);
263 _bend
= __write_integer(_buf
, 0, (long)((long)t
->tm_yday
+ 1));
264 __append(buf
, _buf
, _bend
, ct
);
268 _STLP_SPRINTF(_buf
, (modifier
!= '#') ? "%.2ld" : "%ld", (long)t
->tm_mon
+ 1);
269 __append(buf
, _buf
, ((long)(t
->tm_mon
+ 1) < 10L && modifier
== '#') ? _buf
+ 1 : _buf
+ 2, ct
);
273 _STLP_SPRINTF(_buf
, (modifier
!= '#') ? "%.2ld" : "%ld", (long)t
->tm_min
);
274 __append(buf
, _buf
, ((long)t
->tm_min
< 10L && modifier
== '#') ? _buf
+ 1 : _buf
+ 2, ct
);
278 __append(buf
, table
._M_am_pm
[t
->tm_hour
/ 12]);
281 case 'S': // pad with zeros
282 _STLP_SPRINTF(_buf
, (modifier
!= '#') ? "%.2ld" : "%ld", (long)t
->tm_sec
);
283 __append(buf
, _buf
, ((long)t
->tm_sec
< 10L && modifier
== '#') ? _buf
+ 1 : _buf
+ 2, ct
);
287 _bend
= __write_integer(_buf
, 0, long((t
->tm_yday
- t
->tm_wday
+ 7) / 7));
288 __append(buf
, _buf
, _bend
, ct
);
292 _bend
= __write_integer(_buf
, 0, (long)t
->tm_wday
);
293 __append(buf
, _buf
, _bend
, ct
);
297 _bend
= __write_integer(_buf
, 0,
298 (long)(t
->tm_wday
== 0 ? (t
->tm_yday
+ 1) / 7 :
299 (t
->tm_yday
+ 8 - t
->tm_wday
) / 7));
300 __append(buf
, _buf
, _bend
, ct
);
304 __subformat(buf
, ct
, (modifier
!= '#') ? table
._M_date_format
305 : table
._M_long_date_format
, table
, t
);
309 __subformat(buf
, ct
, table
._M_time_format
, table
, t
);
313 _bend
= __write_integer(_buf
, 0, (long)((long)(t
->tm_year
+ 1900) % 100));
314 __append(buf
, _buf
, _bend
, ct
);
318 _bend
= __write_integer(_buf
, 0, (long)((long)t
->tm_year
+ 1900));
319 __append(buf
, _buf
, _bend
, ct
);
323 buf
.append(1, ct
.widen('%'));
326 #if defined (__GNUC__)
327 // fbp : at least on SUN
328 # if defined (_STLP_UNIX) && !defined (__linux__)
332 /*********************************************
333 * JGS, handle various extensions *
334 *********************************************/
336 case 'h': /* POSIX.2 extension */
337 // same as 'b', abbrev month name
338 __append(buf
, table
._M_monthname
[t
->tm_mon
]);
340 case 'C': /* POSIX.2 extension */
341 // same as 'd', the day
342 _STLP_SPRINTF(_buf
, "%2ld", (long)t
->tm_mday
);
343 __append(buf
, _buf
, _buf
+ 2, ct
);
346 case 'D': /* POSIX.2 extension */
348 __subformat(buf
, ct
, table
._M_date_format
, table
, t
);
351 case 'k': /* GNU extension */
352 _STLP_SPRINTF(_buf
, "%2ld", (long)t
->tm_hour
);
353 __append(buf
, _buf
, _buf
+ 2, ct
);
356 case 'l': /* GNU extension */
357 _STLP_SPRINTF(_buf
, "%2ld", (long)t
->tm_hour
% 12);
358 __append(buf
, _buf
, _buf
+ 2, ct
);
361 case 'n': /* POSIX.2 extension */
362 buf
.append(1, ct
.widen('\n'));
365 case 'R': /* GNU extension */
366 __subformat(buf
, ct
, "%H:%M", table
, t
);
369 case 'r': /* POSIX.2 extension */
370 __subformat(buf
, ct
, "%I:%M:%S %p", table
, t
);
373 case 'T': /* POSIX.2 extension. */
374 __subformat(buf
, ct
, "%H:%M:%S", table
, t
);
377 case 't': /* POSIX.2 extension. */
378 buf
.append(1, ct
.widen('\t'));
380 case 'u': /* POSIX.2 extension. */
381 _bend
= __write_integer(_buf
, 0, long((t
->tm_wday
- 1 + 7)) % 7 + 1);
382 __append(buf
, _buf
, _bend
, ct
);
386 time_t __t
= mktime(__CONST_CAST(tm
*, t
));
387 _bend
= __write_integer(_buf
, 0, (long)__t
);
388 __append(buf
, _buf
, _bend
, ct
);
391 case 'g': /* GNU extension */
393 int year
= t
->tm_year
+ __TM_YEAR_BASE
;
394 int days
= __iso_week_days (t
->tm_yday
, t
->tm_wday
);
396 /* This ISO week belongs to the previous year. */
398 days
= __iso_week_days (t
->tm_yday
+ (365 + __is_leap (year
)), t
->tm_wday
);
401 int d
= __iso_week_days (t
->tm_yday
- (365 + __is_leap (year
)), t
->tm_wday
);
403 /* This ISO week belongs to the next year. */
411 val
= (long)(year
% 100 + 100) % 100;
417 val
= (long)days
/ 7 + 1;
420 _bend
= __write_integer(_buf
, 0, val
);
421 __append(buf
, _buf
, _bend
, ct
);
425 # if defined (_STLP_USE_GLIBC)
426 case 'z': /* GNU extension. */
431 # if defined (__USE_BSD) || defined (__BEOS__)
434 diff
= t
->__tm_gmtoff
;
437 buf
.append(1, ct
.widen('-'));
440 buf
.append(1, ct
.widen('+'));
442 _STLP_SPRINTF(_buf
, "%.4d", (diff
/ 60) * 100 + diff
% 60);
443 __append(buf
, _buf
, _buf
+ 4, ct
);
446 # endif /* __GLIBC__ */
447 #endif /* __GNUC__ */
454 void _STLP_CALL
__write_formatted_time(__iostring
&buf
, const ctype
<char>& ct
,
455 char format
, char modifier
,
456 const _Time_Info
& table
, const tm
* t
)
457 { __write_formatted_timeT(buf
, ct
, format
, modifier
, table
, t
); }
459 void _STLP_CALL
__write_formatted_time(__iowstring
&buf
, const ctype
<wchar_t>& ct
,
460 char format
, char modifier
,
461 const _WTime_Info
& table
, const tm
* t
)
462 { __write_formatted_timeT(buf
, ct
, format
, modifier
, table
, t
); }
464 static time_base::dateorder
__get_date_order(_Locale_time
* time
) {
465 const char * fmt
= _Locale_d_fmt(time
);
466 char first
, second
, third
;
468 while (*fmt
!= 0 && *fmt
!= '%') ++fmt
;
470 return time_base::no_order
;
472 while (*fmt
!= 0 && *fmt
!= '%') ++fmt
;
474 return time_base::no_order
;
476 while (*fmt
!= 0 && *fmt
!= '%') ++fmt
;
478 return time_base::no_order
;
483 return (second
== 'm' && third
== 'y') ? time_base::dmy
484 : time_base::no_order
;
486 return (second
== 'd' && third
== 'y') ? time_base::mdy
487 : time_base::no_order
;
491 return third
== 'm' ? time_base::ydm
: time_base::no_order
;
493 return third
== 'd' ? time_base::ymd
: time_base::no_order
;
495 return time_base::no_order
;
498 return time_base::no_order
;
502 time_init
<char>::time_init()
503 : _M_dateorder(time_base::no_order
)
504 { _Init_timeinfo(_M_timeinfo
); }
506 time_init
<char>::time_init(const char* __name
) {
508 locale::_M_throw_on_null_name();
511 char buf
[_Locale_MAX_SIMPLE_NAME
];
512 _Locale_time
*__time
= __acquire_time(__name
, buf
, 0, &__err_code
);
514 locale::_M_throw_on_creation_failure(__err_code
, __name
, "time");
516 _Init_timeinfo(this->_M_timeinfo
, __time
);
517 _M_dateorder
= __get_date_order(__time
);
518 __release_time(__time
);
521 time_init
<char>::time_init(_Locale_time
*__time
) {
522 _Init_timeinfo(this->_M_timeinfo
, __time
);
523 _M_dateorder
= __get_date_order(__time
);
526 #ifndef _STLP_NO_WCHAR_T
527 time_init
<wchar_t>::time_init()
528 : _M_dateorder(time_base::no_order
)
529 { _Init_timeinfo(_M_timeinfo
); }
531 time_init
<wchar_t>::time_init(const char* __name
) {
533 locale::_M_throw_on_null_name();
536 char buf
[_Locale_MAX_SIMPLE_NAME
];
537 _Locale_time
*__time
= __acquire_time(__name
, buf
, 0, &__err_code
);
539 locale::_M_throw_on_creation_failure(__err_code
, __name
, "time");
541 _Init_timeinfo(this->_M_timeinfo
, __time
);
542 _M_dateorder
= __get_date_order(__time
);
543 __release_time(__time
);
546 time_init
<wchar_t>::time_init(_Locale_time
*__time
) {
547 _Init_timeinfo(this->_M_timeinfo
, __time
);
548 _M_dateorder
= __get_date_order(__time
);
552 _STLP_MOVE_TO_STD_NAMESPACE
554 #if !defined (_STLP_NO_FORCE_INSTANTIATE)
555 template class time_get
<char, istreambuf_iterator
<char, char_traits
<char> > >;
556 template class time_put
<char, ostreambuf_iterator
<char, char_traits
<char> > >;
558 # ifndef _STLP_NO_WCHAR_T
559 template class time_get
<wchar_t, istreambuf_iterator
<wchar_t, char_traits
<wchar_t> > >;
560 template class time_put
<wchar_t, ostreambuf_iterator
<wchar_t, char_traits
<wchar_t> > >;