File indexing completed on 2025-01-18 09:30:39
0001
0002 #ifndef _DATE_TIME_FACET__HPP__
0003 #define _DATE_TIME_FACET__HPP__
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <cctype>
0014 #include <exception>
0015 #include <iomanip>
0016 #include <iterator> // i/ostreambuf_iterator
0017 #include <locale>
0018 #include <limits>
0019 #include <sstream>
0020 #include <string>
0021 #include <boost/assert.hpp>
0022 #include <boost/lexical_cast.hpp>
0023 #include <boost/throw_exception.hpp>
0024 #include <boost/range/as_literal.hpp>
0025 #include <boost/algorithm/string/erase.hpp>
0026 #include <boost/algorithm/string/replace.hpp>
0027 #include <boost/date_time/compiler_config.hpp>
0028 #include <boost/date_time/date_facet.hpp>
0029 #include <boost/date_time/string_convert.hpp>
0030 #include <boost/date_time/special_defs.hpp>
0031 #include <boost/date_time/time_resolution_traits.hpp> // absolute_value
0032
0033 namespace boost {
0034 namespace date_time {
0035
0036 template <class CharT>
0037 struct time_formats {
0038 public:
0039 typedef CharT char_type;
0040 static const char_type fractional_seconds_format[3];
0041 static const char_type fractional_seconds_or_none_format[3];
0042 static const char_type seconds_with_fractional_seconds_format[3];
0043 static const char_type seconds_format[3];
0044 static const char_type hours_format[3];
0045 static const char_type unrestricted_hours_format[3];
0046 static const char_type full_24_hour_time_format[3];
0047 static const char_type full_24_hour_time_expanded_format[9];
0048 static const char_type short_24_hour_time_format[3];
0049 static const char_type short_24_hour_time_expanded_format[6];
0050 static const char_type standard_format[9];
0051 static const char_type zone_abbrev_format[3];
0052 static const char_type zone_name_format[3];
0053 static const char_type zone_iso_format[3];
0054 static const char_type zone_iso_extended_format[3];
0055 static const char_type posix_zone_string_format[4];
0056 static const char_type duration_sign_negative_only[3];
0057 static const char_type duration_sign_always[3];
0058 static const char_type duration_seperator[2];
0059 static const char_type negative_sign[2];
0060 static const char_type positive_sign[2];
0061 static const char_type iso_time_format_specifier[18];
0062 static const char_type iso_time_format_extended_specifier[22];
0063
0064 static const char_type default_time_format[23];
0065
0066 static const char_type default_time_input_format[24];
0067
0068 static const char_type default_time_duration_format[11];
0069 };
0070
0071 template <class CharT>
0072 const typename time_formats<CharT>::char_type
0073 time_formats<CharT>::fractional_seconds_format[3] = {'%','f'};
0074
0075 template <class CharT>
0076 const typename time_formats<CharT>::char_type
0077 time_formats<CharT>::fractional_seconds_or_none_format[3] = {'%','F'};
0078
0079 template <class CharT>
0080 const typename time_formats<CharT>::char_type
0081 time_formats<CharT>::seconds_with_fractional_seconds_format[3] = {'%','s'};
0082
0083 template <class CharT>
0084 const typename time_formats<CharT>::char_type
0085 time_formats<CharT>::seconds_format[3] = {'%','S'};
0086
0087 template <class CharT>
0088 const typename time_formats<CharT>::char_type
0089 time_formats<CharT>::hours_format[3] = {'%','H'};
0090
0091 template <class CharT>
0092 const typename time_formats<CharT>::char_type
0093 time_formats<CharT>::unrestricted_hours_format[3] = {'%','O'};
0094
0095 template <class CharT>
0096 const typename time_formats<CharT>::char_type
0097 time_formats<CharT>::full_24_hour_time_format[3] = {'%','T'};
0098
0099 template <class CharT>
0100 const typename time_formats<CharT>::char_type
0101 time_formats<CharT>::full_24_hour_time_expanded_format[9] =
0102 {'%','H',':','%','M',':','%','S'};
0103
0104 template <class CharT>
0105 const typename time_formats<CharT>::char_type
0106 time_formats<CharT>::short_24_hour_time_format[3] = {'%','R'};
0107
0108 template <class CharT>
0109 const typename time_formats<CharT>::char_type
0110 time_formats<CharT>::short_24_hour_time_expanded_format[6] =
0111 {'%','H',':','%','M'};
0112
0113 template <class CharT>
0114 const typename time_formats<CharT>::char_type
0115
0116 time_formats<CharT>::standard_format[9] = {'%','x',' ','%','X',' ','%','z'};
0117
0118 template <class CharT>
0119 const typename time_formats<CharT>::char_type
0120 time_formats<CharT>::zone_abbrev_format[3] = {'%','z'};
0121
0122 template <class CharT>
0123 const typename time_formats<CharT>::char_type
0124 time_formats<CharT>::zone_name_format[3] = {'%','Z'};
0125
0126 template <class CharT>
0127 const typename time_formats<CharT>::char_type
0128 time_formats<CharT>::zone_iso_format[3] = {'%','q'};
0129
0130 template <class CharT>
0131 const typename time_formats<CharT>::char_type
0132 time_formats<CharT>::zone_iso_extended_format[3] ={'%','Q'};
0133
0134 template <class CharT>
0135 const typename time_formats<CharT>::char_type
0136 time_formats<CharT>::posix_zone_string_format[4] ={'%','Z','P'};
0137
0138 template <class CharT>
0139 const typename time_formats<CharT>::char_type
0140 time_formats<CharT>::duration_seperator[2] = {':'};
0141
0142 template <class CharT>
0143 const typename time_formats<CharT>::char_type
0144 time_formats<CharT>::negative_sign[2] = {'-'};
0145
0146 template <class CharT>
0147 const typename time_formats<CharT>::char_type
0148 time_formats<CharT>::positive_sign[2] = {'+'};
0149
0150 template <class CharT>
0151 const typename time_formats<CharT>::char_type
0152 time_formats<CharT>::duration_sign_negative_only[3] ={'%','-'};
0153
0154 template <class CharT>
0155 const typename time_formats<CharT>::char_type
0156 time_formats<CharT>::duration_sign_always[3] ={'%','+'};
0157
0158 template <class CharT>
0159 const typename time_formats<CharT>::char_type
0160 time_formats<CharT>::iso_time_format_specifier[18] =
0161 {'%', 'Y', '%', 'm', '%', 'd', 'T',
0162 '%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' };
0163
0164 template <class CharT>
0165 const typename time_formats<CharT>::char_type
0166 time_formats<CharT>::iso_time_format_extended_specifier[22] =
0167 {'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ',
0168 '%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'};
0169
0170 template <class CharT>
0171 const typename time_formats<CharT>::char_type
0172 time_formats<CharT>::default_time_format[23] =
0173 {'%','Y','-','%','b','-','%','d',' ',
0174 '%','H',':','%','M',':','%','S','%','F',' ','%','z'};
0175
0176 template <class CharT>
0177 const typename time_formats<CharT>::char_type
0178 time_formats<CharT>::default_time_input_format[24] =
0179 {'%','Y','-','%','b','-','%','d',' ',
0180 '%','H',':','%','M',':','%','S','%','F',' ','%','Z','P'};
0181
0182 template <class CharT>
0183 const typename time_formats<CharT>::char_type
0184 time_formats<CharT>::default_time_duration_format[11] =
0185 {'%','O',':','%','M',':','%','S','%','F'};
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200 template <class time_type,
0201 class CharT,
0202 class OutItrT = std::ostreambuf_iterator<CharT, std::char_traits<CharT> > >
0203 class BOOST_SYMBOL_VISIBLE time_facet :
0204 public boost::date_time::date_facet<typename time_type::date_type , CharT, OutItrT> {
0205 typedef time_formats< CharT > formats_type;
0206 public:
0207 typedef typename time_type::date_type date_type;
0208 typedef typename time_type::time_duration_type time_duration_type;
0209 typedef boost::date_time::period<time_type,time_duration_type> period_type;
0210 typedef boost::date_time::date_facet<typename time_type::date_type, CharT, OutItrT> base_type;
0211 typedef typename base_type::string_type string_type;
0212 typedef typename base_type::char_type char_type;
0213 typedef typename base_type::period_formatter_type period_formatter_type;
0214 typedef typename base_type::special_values_formatter_type special_values_formatter_type;
0215 typedef typename base_type::date_gen_formatter_type date_gen_formatter_type;
0216 static const char_type* fractional_seconds_format;
0217 static const char_type* fractional_seconds_or_none_format;
0218 static const char_type* seconds_with_fractional_seconds_format;
0219 static const char_type* seconds_format;
0220 static const char_type* hours_format;
0221 static const char_type* unrestricted_hours_format;
0222 static const char_type* standard_format;
0223 static const char_type* zone_abbrev_format;
0224 static const char_type* zone_name_format;
0225 static const char_type* zone_iso_format;
0226 static const char_type* zone_iso_extended_format;
0227 static const char_type* posix_zone_string_format;
0228 static const char_type* duration_seperator;
0229 static const char_type* duration_sign_always;
0230 static const char_type* duration_sign_negative_only;
0231 static const char_type* negative_sign;
0232 static const char_type* positive_sign;
0233 static const char_type* iso_time_format_specifier;
0234 static const char_type* iso_time_format_extended_specifier;
0235
0236
0237 static const char_type* default_time_format;
0238
0239 static const char_type* default_time_duration_format;
0240 static std::locale::id id;
0241
0242 #if defined (__SUNPRO_CC) && defined (_RWSTD_VER)
0243 std::locale::id& __get_id (void) const { return id; }
0244 #endif
0245
0246
0247 explicit time_facet(::size_t ref_arg = 0)
0248 : base_type(default_time_format, period_formatter_type(), special_values_formatter_type(), date_gen_formatter_type(), ref_arg),
0249 m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format)
0250 {}
0251
0252
0253 explicit time_facet(const char_type* format_arg,
0254 period_formatter_type period_formatter_arg = period_formatter_type(),
0255 const special_values_formatter_type& special_value_formatter = special_values_formatter_type(),
0256 date_gen_formatter_type dg_formatter = date_gen_formatter_type(),
0257 ::size_t ref_arg = 0)
0258 : base_type(format_arg,
0259 period_formatter_arg,
0260 special_value_formatter,
0261 dg_formatter,
0262 ref_arg),
0263 m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format)
0264 {}
0265
0266
0267 void time_duration_format(const char_type* const format)
0268 {
0269 m_time_duration_format = format;
0270 }
0271
0272 void set_iso_format() BOOST_OVERRIDE
0273 {
0274 this->m_format = iso_time_format_specifier;
0275 }
0276 void set_iso_extended_format() BOOST_OVERRIDE
0277 {
0278 this->m_format = iso_time_format_extended_specifier;
0279 }
0280
0281 OutItrT put(OutItrT next_arg,
0282 std::ios_base& ios_arg,
0283 char_type fill_arg,
0284 const time_type& time_arg) const
0285 {
0286 if (time_arg.is_special()) {
0287 return this->do_put_special(next_arg, ios_arg, fill_arg,
0288 time_arg.date().as_special());
0289 }
0290 string_type local_format(this->m_format);
0291
0292
0293 boost::algorithm::replace_all(local_format,
0294 boost::as_literal(formats_type::full_24_hour_time_format),
0295 boost::as_literal(formats_type::full_24_hour_time_expanded_format));
0296 boost::algorithm::replace_all(local_format,
0297 boost::as_literal(formats_type::short_24_hour_time_format),
0298 boost::as_literal(formats_type::short_24_hour_time_expanded_format));
0299
0300 string_type frac_str;
0301 if (local_format.find(seconds_with_fractional_seconds_format) != string_type::npos) {
0302
0303 frac_str =
0304 fractional_seconds_as_string(time_arg.time_of_day(), false);
0305 char_type sep = std::use_facet<std::numpunct<char_type> >(ios_arg.getloc()).decimal_point();
0306
0307 string_type replace_string(seconds_format);
0308 replace_string += sep;
0309 replace_string += frac_str;
0310 boost::algorithm::replace_all(local_format,
0311 seconds_with_fractional_seconds_format,
0312 replace_string);
0313 }
0314
0315
0316
0317 if (local_format.find(posix_zone_string_format) != string_type::npos) {
0318 if(time_arg.zone_abbrev().empty()) {
0319
0320
0321 boost::algorithm::erase_all(local_format, posix_zone_string_format);
0322 }
0323 else{
0324 boost::algorithm::replace_all(local_format,
0325 posix_zone_string_format,
0326 time_arg.zone_as_posix_string());
0327 }
0328 }
0329 if (local_format.find(zone_name_format) != string_type::npos) {
0330 if(time_arg.zone_name().empty()) {
0331
0332
0333
0334
0335
0336
0337 std::basic_ostringstream<char_type> ss;
0338 ss << ' ' << zone_name_format;
0339 boost::algorithm::erase_all(local_format, ss.str());
0340 }
0341 else{
0342 boost::algorithm::replace_all(local_format,
0343 zone_name_format,
0344 time_arg.zone_name());
0345 }
0346 }
0347 if (local_format.find(zone_abbrev_format) != string_type::npos) {
0348 if(time_arg.zone_abbrev(false).empty()) {
0349
0350
0351
0352
0353
0354
0355 std::basic_ostringstream<char_type> ss;
0356 ss << ' ' << zone_abbrev_format;
0357 boost::algorithm::erase_all(local_format, ss.str());
0358 }
0359 else{
0360 boost::algorithm::replace_all(local_format,
0361 zone_abbrev_format,
0362 time_arg.zone_abbrev(false));
0363 }
0364 }
0365 if (local_format.find(zone_iso_extended_format) != string_type::npos) {
0366 if(time_arg.zone_name(true).empty()) {
0367
0368
0369
0370
0371
0372
0373 boost::algorithm::erase_all(local_format, zone_iso_extended_format);
0374 }
0375 else{
0376 boost::algorithm::replace_all(local_format,
0377 zone_iso_extended_format,
0378 time_arg.zone_name(true));
0379 }
0380 }
0381
0382 if (local_format.find(zone_iso_format) != string_type::npos) {
0383 if(time_arg.zone_abbrev(true).empty()) {
0384
0385
0386
0387
0388
0389
0390 boost::algorithm::erase_all(local_format, zone_iso_format);
0391 }
0392 else{
0393 boost::algorithm::replace_all(local_format,
0394 zone_iso_format,
0395 time_arg.zone_abbrev(true));
0396 }
0397 }
0398 if (local_format.find(fractional_seconds_format) != string_type::npos) {
0399
0400 if (frac_str.empty()) {
0401 frac_str = fractional_seconds_as_string(time_arg.time_of_day(), false);
0402 }
0403 boost::algorithm::replace_all(local_format,
0404 fractional_seconds_format,
0405 frac_str);
0406 }
0407
0408 if (local_format.find(fractional_seconds_or_none_format) != string_type::npos) {
0409
0410 frac_str =
0411 fractional_seconds_as_string(time_arg.time_of_day(), true);
0412 if (!frac_str.empty()) {
0413 char_type sep = std::use_facet<std::numpunct<char_type> >(ios_arg.getloc()).decimal_point();
0414 string_type replace_string;
0415 replace_string += sep;
0416 replace_string += frac_str;
0417 boost::algorithm::replace_all(local_format,
0418 fractional_seconds_or_none_format,
0419 replace_string);
0420 }
0421 else {
0422 boost::algorithm::erase_all(local_format,
0423 fractional_seconds_or_none_format);
0424 }
0425 }
0426
0427 return this->do_put_tm(next_arg, ios_arg, fill_arg,
0428 to_tm(time_arg), local_format);
0429 }
0430
0431
0432 OutItrT put(OutItrT next_arg,
0433 std::ios_base& ios_arg,
0434 char_type fill_arg,
0435 const time_duration_type& time_dur_arg) const
0436 {
0437 if (time_dur_arg.is_special()) {
0438 return this->do_put_special(next_arg, ios_arg, fill_arg,
0439 time_dur_arg.get_rep().as_special());
0440 }
0441
0442 string_type format(m_time_duration_format);
0443 if (time_dur_arg.is_negative()) {
0444
0445 boost::algorithm::replace_all(format,
0446 duration_sign_negative_only,
0447 negative_sign);
0448
0449 boost::algorithm::replace_all(format,
0450 duration_sign_always,
0451 negative_sign);
0452 }
0453 else {
0454
0455 boost::algorithm::erase_all(format, duration_sign_negative_only);
0456
0457 boost::algorithm::replace_all(format,
0458 duration_sign_always,
0459 positive_sign);
0460 }
0461
0462
0463 boost::algorithm::replace_all(format,
0464 boost::as_literal(formats_type::full_24_hour_time_format),
0465 boost::as_literal(formats_type::full_24_hour_time_expanded_format));
0466 boost::algorithm::replace_all(format,
0467 boost::as_literal(formats_type::short_24_hour_time_format),
0468 boost::as_literal(formats_type::short_24_hour_time_expanded_format));
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478 string_type hours_str;
0479 if (format.find(unrestricted_hours_format) != string_type::npos) {
0480 hours_str = hours_as_string(time_dur_arg);
0481 boost::algorithm::replace_all(format, unrestricted_hours_format, hours_str);
0482 }
0483
0484
0485
0486 if (format.find(hours_format) != string_type::npos) {
0487 if (hours_str.empty())
0488 hours_str = hours_as_string(time_dur_arg);
0489 BOOST_ASSERT(hours_str.length() <= 2);
0490 boost::algorithm::replace_all(format, hours_format, hours_str);
0491 }
0492
0493 string_type frac_str;
0494 if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) {
0495
0496 frac_str =
0497 fractional_seconds_as_string(time_dur_arg, false);
0498 char_type sep = std::use_facet<std::numpunct<char_type> >(ios_arg.getloc()).decimal_point();
0499
0500 string_type replace_string(seconds_format);
0501 replace_string += sep;
0502 replace_string += frac_str;
0503 boost::algorithm::replace_all(format,
0504 seconds_with_fractional_seconds_format,
0505 replace_string);
0506 }
0507 if (format.find(fractional_seconds_format) != string_type::npos) {
0508
0509 if (!frac_str.size()) {
0510 frac_str = fractional_seconds_as_string(time_dur_arg, false);
0511 }
0512 boost::algorithm::replace_all(format,
0513 fractional_seconds_format,
0514 frac_str);
0515 }
0516
0517 if (format.find(fractional_seconds_or_none_format) != string_type::npos) {
0518
0519 frac_str =
0520 fractional_seconds_as_string(time_dur_arg, true);
0521 if (frac_str.size()) {
0522 char_type sep = std::use_facet<std::numpunct<char_type> >(ios_arg.getloc()).decimal_point();
0523 string_type replace_string;
0524 replace_string += sep;
0525 replace_string += frac_str;
0526 boost::algorithm::replace_all(format,
0527 fractional_seconds_or_none_format,
0528 replace_string);
0529 }
0530 else {
0531 boost::algorithm::erase_all(format,
0532 fractional_seconds_or_none_format);
0533 }
0534 }
0535
0536 return this->do_put_tm(next_arg, ios_arg, fill_arg,
0537 to_tm(time_dur_arg), format);
0538 }
0539
0540 OutItrT put(OutItrT next, std::ios_base& ios_arg,
0541 char_type fill, const period_type& p) const
0542 {
0543 return this->m_period_formatter.put_period(next, ios_arg, fill,p,*this);
0544 }
0545
0546
0547 protected:
0548
0549 static
0550 string_type
0551 fractional_seconds_as_string(const time_duration_type& time_arg,
0552 bool null_when_zero)
0553 {
0554 typename time_duration_type::fractional_seconds_type frac_sec =
0555 time_arg.fractional_seconds();
0556
0557 if (null_when_zero && (frac_sec == 0)) {
0558 return string_type();
0559 }
0560
0561
0562 return integral_as_string(
0563 date_time::absolute_value(frac_sec),
0564 time_duration_type::num_fractional_digits());
0565 }
0566
0567 static
0568 string_type
0569 hours_as_string(const time_duration_type& time_arg, int width = 2)
0570 {
0571 return integral_as_string(date_time::absolute_value(time_arg.hours()), width);
0572 }
0573
0574 template< typename IntT >
0575 static
0576 string_type
0577 integral_as_string(IntT val, int width = 2)
0578 {
0579 std::basic_ostringstream<char_type> ss;
0580 ss.imbue(std::locale::classic());
0581 ss << std::setw(width)
0582 << std::setfill(static_cast<char_type>('0'));
0583 #if (defined(BOOST_MSVC) && (_MSC_VER < 1300))
0584
0585 char_type buff[34];
0586 ss << _i64toa(static_cast<boost::int64_t>(val), buff, 10);
0587 #else
0588 ss << val;
0589 #endif
0590 return ss.str();
0591 }
0592
0593 private:
0594 string_type m_time_duration_format;
0595
0596 };
0597
0598 template <class time_type, class CharT, class OutItrT>
0599 std::locale::id time_facet<time_type, CharT, OutItrT>::id;
0600
0601 template <class time_type, class CharT, class OutItrT>
0602 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0603 time_facet<time_type, CharT, OutItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format;
0604
0605 template <class time_type, class CharT, class OutItrT>
0606 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0607 time_facet<time_type, CharT, OutItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format;
0608
0609 template <class time_type, class CharT, class OutItrT>
0610 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0611 time_facet<time_type, CharT, OutItrT>::seconds_with_fractional_seconds_format =
0612 time_formats<CharT>::seconds_with_fractional_seconds_format;
0613
0614
0615 template <class time_type, class CharT, class OutItrT>
0616 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0617 time_facet<time_type, CharT, OutItrT>::zone_name_format = time_formats<CharT>::zone_name_format;
0618
0619 template <class time_type, class CharT, class OutItrT>
0620 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0621 time_facet<time_type, CharT, OutItrT>::zone_abbrev_format = time_formats<CharT>::zone_abbrev_format;
0622
0623 template <class time_type, class CharT, class OutItrT>
0624 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0625 time_facet<time_type, CharT, OutItrT>::zone_iso_extended_format =time_formats<CharT>::zone_iso_extended_format;
0626
0627 template <class time_type, class CharT, class OutItrT>
0628 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0629 time_facet<time_type, CharT, OutItrT>::posix_zone_string_format =time_formats<CharT>::posix_zone_string_format;
0630
0631 template <class time_type, class CharT, class OutItrT>
0632 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0633 time_facet<time_type, CharT, OutItrT>::zone_iso_format = time_formats<CharT>::zone_iso_format;
0634
0635 template <class time_type, class CharT, class OutItrT>
0636 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0637 time_facet<time_type, CharT, OutItrT>::seconds_format = time_formats<CharT>::seconds_format;
0638
0639 template <class time_type, class CharT, class OutItrT>
0640 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0641 time_facet<time_type, CharT, OutItrT>::hours_format = time_formats<CharT>::hours_format;
0642
0643 template <class time_type, class CharT, class OutItrT>
0644 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0645 time_facet<time_type, CharT, OutItrT>::unrestricted_hours_format = time_formats<CharT>::unrestricted_hours_format;
0646
0647 template <class time_type, class CharT, class OutItrT>
0648 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0649 time_facet<time_type, CharT, OutItrT>::standard_format = time_formats<CharT>::standard_format;
0650
0651 template <class time_type, class CharT, class OutItrT>
0652 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0653 time_facet<time_type, CharT, OutItrT>::duration_seperator = time_formats<CharT>::duration_seperator;
0654
0655 template <class time_type, class CharT, class OutItrT>
0656 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0657 time_facet<time_type, CharT, OutItrT>::negative_sign = time_formats<CharT>::negative_sign;
0658
0659 template <class time_type, class CharT, class OutItrT>
0660 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0661 time_facet<time_type, CharT, OutItrT>::positive_sign = time_formats<CharT>::positive_sign;
0662
0663 template <class time_type, class CharT, class OutItrT>
0664 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0665 time_facet<time_type, CharT, OutItrT>::duration_sign_negative_only = time_formats<CharT>::duration_sign_negative_only;
0666
0667 template <class time_type, class CharT, class OutItrT>
0668 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0669 time_facet<time_type, CharT, OutItrT>::duration_sign_always = time_formats<CharT>::duration_sign_always;
0670
0671 template <class time_type, class CharT, class OutItrT>
0672 const typename time_facet<time_type,CharT, OutItrT>::char_type*
0673 time_facet<time_type,CharT, OutItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier;
0674
0675 template <class time_type, class CharT, class OutItrT>
0676 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0677 time_facet<time_type, CharT, OutItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier;
0678
0679 template <class time_type, class CharT, class OutItrT>
0680 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0681 time_facet<time_type, CharT, OutItrT>::default_time_format =
0682 time_formats<CharT>::default_time_format;
0683
0684 template <class time_type, class CharT, class OutItrT>
0685 const typename time_facet<time_type, CharT, OutItrT>::char_type*
0686 time_facet<time_type, CharT, OutItrT>::default_time_duration_format =
0687 time_formats<CharT>::default_time_duration_format;
0688
0689
0690
0691
0692
0693 template <class time_type,
0694 class CharT,
0695 class InItrT = std::istreambuf_iterator<CharT, std::char_traits<CharT> > >
0696 class BOOST_SYMBOL_VISIBLE time_input_facet :
0697 public boost::date_time::date_input_facet<typename time_type::date_type , CharT, InItrT> {
0698 public:
0699 typedef typename time_type::date_type date_type;
0700 typedef typename time_type::time_duration_type time_duration_type;
0701 typedef typename time_duration_type::fractional_seconds_type fracional_seconds_type;
0702 typedef boost::date_time::period<time_type,time_duration_type> period_type;
0703 typedef boost::date_time::date_input_facet<typename time_type::date_type, CharT, InItrT> base_type;
0704 typedef typename base_type::duration_type date_duration_type;
0705 typedef typename base_type::year_type year_type;
0706 typedef typename base_type::month_type month_type;
0707 typedef typename base_type::day_type day_type;
0708 typedef typename base_type::string_type string_type;
0709 typedef typename string_type::const_iterator const_itr;
0710 typedef typename base_type::char_type char_type;
0711 typedef typename base_type::format_date_parser_type format_date_parser_type;
0712 typedef typename base_type::period_parser_type period_parser_type;
0713 typedef typename base_type::special_values_parser_type special_values_parser_type;
0714 typedef typename base_type::date_gen_parser_type date_gen_parser_type;
0715 typedef typename base_type::special_values_parser_type::match_results match_results;
0716
0717 static const char_type* fractional_seconds_format;
0718 static const char_type* fractional_seconds_or_none_format;
0719 static const char_type* seconds_with_fractional_seconds_format;
0720 static const char_type* seconds_format;
0721 static const char_type* standard_format;
0722 static const char_type* zone_abbrev_format;
0723 static const char_type* zone_name_format;
0724 static const char_type* zone_iso_format;
0725 static const char_type* zone_iso_extended_format;
0726 static const char_type* duration_seperator;
0727 static const char_type* iso_time_format_specifier;
0728 static const char_type* iso_time_format_extended_specifier;
0729 static const char_type* default_time_input_format;
0730 static const char_type* default_time_duration_format;
0731 static std::locale::id id;
0732
0733
0734 explicit time_input_facet(const string_type& format, ::size_t ref_arg = 0)
0735 : base_type(format, ref_arg),
0736 m_time_duration_format(default_time_duration_format)
0737 { }
0738
0739 explicit time_input_facet(const string_type& format,
0740 const format_date_parser_type& date_parser,
0741 const special_values_parser_type& sv_parser,
0742 const period_parser_type& per_parser,
0743 const date_gen_parser_type& date_gen_parser,
0744 ::size_t ref_arg = 0)
0745 : base_type(format,
0746 date_parser,
0747 sv_parser,
0748 per_parser,
0749 date_gen_parser,
0750 ref_arg),
0751 m_time_duration_format(default_time_duration_format)
0752 {}
0753
0754
0755 explicit time_input_facet(::size_t ref_arg = 0)
0756 : base_type(default_time_input_format, ref_arg),
0757 m_time_duration_format(default_time_duration_format)
0758 { }
0759
0760
0761 void time_duration_format(const char_type* const format) {
0762 m_time_duration_format = format;
0763 }
0764 virtual void set_iso_format()
0765 {
0766 this->m_format = iso_time_format_specifier;
0767 }
0768 virtual void set_iso_extended_format()
0769 {
0770 this->m_format = iso_time_format_extended_specifier;
0771 }
0772
0773 InItrT get(InItrT& sitr,
0774 InItrT& stream_end,
0775 std::ios_base& ios_arg,
0776 period_type& p) const
0777 {
0778 p = this->m_period_parser.get_period(sitr,
0779 stream_end,
0780 ios_arg,
0781 p,
0782 time_duration_type::unit(),
0783 *this);
0784 return sitr;
0785 }
0786
0787
0788
0789
0790 InItrT get(InItrT& sitr,
0791 InItrT& stream_end,
0792 std::ios_base& ios_arg,
0793 time_duration_type& td) const
0794 {
0795
0796 while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
0797
0798 bool use_current_char = false;
0799
0800
0801 char_type c = '\0';
0802 if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
0803 c = *sitr;
0804 }
0805
0806 typedef typename time_duration_type::hour_type hour_type;
0807 typedef typename time_duration_type::min_type min_type;
0808 typedef typename time_duration_type::sec_type sec_type;
0809
0810 hour_type hour = 0;
0811 min_type min = 0;
0812 sec_type sec = 0;
0813 typename time_duration_type::fractional_seconds_type frac(0);
0814
0815 typedef std::num_get<CharT, InItrT> num_get;
0816 if(!std::has_facet<num_get>(ios_arg.getloc())) {
0817 num_get* ng = new num_get();
0818 std::locale loc = std::locale(ios_arg.getloc(), ng);
0819 ios_arg.imbue(loc);
0820 }
0821
0822 const_itr itr(m_time_duration_format.begin());
0823 while (itr != m_time_duration_format.end() && (sitr != stream_end)) {
0824 if (*itr == '%') {
0825 if (++itr == m_time_duration_format.end()) break;
0826 if (*itr != '%') {
0827 switch(*itr) {
0828 case 'O':
0829 {
0830
0831
0832 hour = var_string_to_int<hour_type, CharT>(sitr, stream_end,
0833 std::numeric_limits<hour_type>::digits10 + 1);
0834 if(hour == -1){
0835 return check_special_value(sitr, stream_end, td, c);
0836 }
0837 break;
0838 }
0839 case 'H':
0840 {
0841 match_results mr;
0842 hour = fixed_string_to_int<hour_type, CharT>(sitr, stream_end, mr, 2);
0843 if(hour == -1){
0844 return check_special_value(sitr, stream_end, td, c);
0845 }
0846 break;
0847 }
0848 case 'M':
0849 {
0850 match_results mr;
0851 min = fixed_string_to_int<min_type, CharT>(sitr, stream_end, mr, 2);
0852 if(min == -1){
0853 return check_special_value(sitr, stream_end, td, c);
0854 }
0855 break;
0856 }
0857 case 's':
0858 case 'S':
0859 {
0860 match_results mr;
0861 sec = fixed_string_to_int<sec_type, CharT>(sitr, stream_end, mr, 2);
0862 if(sec == -1){
0863 return check_special_value(sitr, stream_end, td, c);
0864 }
0865 if (*itr == 'S')
0866 break;
0867
0868 }
0869
0870 case 'f':
0871 {
0872
0873 if(*sitr == '.') {
0874 ++sitr;
0875 parse_frac_type(sitr, stream_end, frac);
0876
0877
0878 use_current_char = true;
0879 }
0880 else {
0881 return check_special_value(sitr, stream_end, td, c);
0882 }
0883 break;
0884 }
0885 case 'F':
0886 {
0887
0888 if(*sitr == '.') {
0889 ++sitr;
0890 parse_frac_type(sitr, stream_end, frac);
0891
0892
0893 use_current_char = true;
0894 }
0895 else {
0896
0897 use_current_char = true;
0898 }
0899 break;
0900 }
0901 default:
0902 {}
0903 }
0904 }
0905 else {
0906 ++sitr;
0907 }
0908
0909 ++itr;
0910 }
0911 else {
0912 ++itr;
0913
0914
0915 if (use_current_char) {
0916 use_current_char = false;
0917 }
0918 else {
0919 ++sitr;
0920 }
0921 }
0922 }
0923
0924 td = time_duration_type(hour, min, sec, frac);
0925 return sitr;
0926 }
0927
0928
0929
0930 InItrT get(InItrT& sitr,
0931 InItrT& stream_end,
0932 std::ios_base& ios_arg,
0933 time_type& t) const
0934 {
0935 string_type tz_str;
0936 return get(sitr, stream_end, ios_arg, t, tz_str, false);
0937 }
0938
0939 InItrT get_local_time(InItrT& sitr,
0940 InItrT& stream_end,
0941 std::ios_base& ios_arg,
0942 time_type& t,
0943 string_type& tz_str) const
0944 {
0945 return get(sitr, stream_end, ios_arg, t, tz_str, true);
0946 }
0947
0948 protected:
0949
0950 InItrT get(InItrT& sitr,
0951 InItrT& stream_end,
0952 std::ios_base& ios_arg,
0953 time_type& t,
0954 string_type& tz_str,
0955 bool time_is_local) const
0956 {
0957
0958 while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
0959
0960 bool use_current_char = false;
0961 bool use_current_format_char = false;
0962
0963
0964 char_type c = '\0';
0965 if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) {
0966 c = *sitr;
0967 }
0968
0969 typedef typename time_duration_type::hour_type hour_type;
0970 typedef typename time_duration_type::min_type min_type;
0971 typedef typename time_duration_type::sec_type sec_type;
0972
0973
0974 hour_type hour = 0;
0975 min_type min = 0;
0976 sec_type sec = 0;
0977 typename time_duration_type::fractional_seconds_type frac(0);
0978
0979 short day_of_year(0);
0980
0981
0982
0983
0984 year_type t_year(1400);
0985 month_type t_month(1);
0986 day_type t_day(1);
0987
0988 typedef std::num_get<CharT, InItrT> num_get;
0989 if(!std::has_facet<num_get>(ios_arg.getloc())) {
0990 num_get* ng = new num_get();
0991 std::locale loc = std::locale(ios_arg.getloc(), ng);
0992 ios_arg.imbue(loc);
0993 }
0994
0995 const_itr itr(this->m_format.begin());
0996 while (itr != this->m_format.end() && (sitr != stream_end)) {
0997 if (*itr == '%') {
0998 if (++itr == this->m_format.end()) break;
0999 if (*itr != '%') {
1000
1001 switch(*itr) {
1002
1003 case 'Y':
1004 case 'y':
1005 {
1006 char_type cs[3] = { '%', *itr };
1007 string_type s(cs);
1008 match_results mr;
1009 try {
1010 t_year = this->m_parser.parse_year(sitr, stream_end, s, mr);
1011 }
1012 catch(std::out_of_range&) {
1013 if(this->m_sv_parser.match(sitr, stream_end, mr)) {
1014 t = time_type(static_cast<special_values>(mr.current_match));
1015 return sitr;
1016 }
1017 else {
1018 throw;
1019 }
1020 }
1021 break;
1022 }
1023 case 'B':
1024 case 'b':
1025 case 'm':
1026 {
1027 char_type cs[3] = { '%', *itr };
1028 string_type s(cs);
1029 match_results mr;
1030 try {
1031 t_month = this->m_parser.parse_month(sitr, stream_end, s, mr);
1032 }
1033 catch(std::out_of_range&) {
1034 if(this->m_sv_parser.match(sitr, stream_end, mr)) {
1035 t = time_type(static_cast<special_values>(mr.current_match));
1036 return sitr;
1037 }
1038 else {
1039 throw;
1040 }
1041 }
1042
1043 if(mr.has_remaining()) {
1044 use_current_char = true;
1045 }
1046 break;
1047 }
1048 case 'a':
1049 case 'A':
1050 case 'w':
1051 {
1052
1053 char_type cs[3] = { '%', *itr };
1054 string_type s(cs);
1055 match_results mr;
1056 typename date_type::day_of_week_type wd(0);
1057 try {
1058 wd = this->m_parser.parse_weekday(sitr, stream_end, s, mr);
1059 }
1060 catch(std::out_of_range&) {
1061 if(this->m_sv_parser.match(sitr, stream_end, mr)) {
1062 t = time_type(static_cast<special_values>(mr.current_match));
1063 return sitr;
1064 }
1065 else {
1066 throw;
1067 }
1068 }
1069
1070 if(mr.has_remaining()) {
1071 use_current_char = true;
1072 }
1073 break;
1074 }
1075 case 'j':
1076 {
1077
1078 match_results mr;
1079 day_of_year = fixed_string_to_int<unsigned short, CharT>(sitr, stream_end, mr, 3);
1080 if(day_of_year == -1) {
1081 if(this->m_sv_parser.match(sitr, stream_end, mr)) {
1082 t = time_type(static_cast<special_values>(mr.current_match));
1083 return sitr;
1084 }
1085 }
1086
1087 typedef typename time_type::date_type::day_of_year_type day_of_year_type;
1088 day_of_year_type t_day_of_year(day_of_year);
1089 break;
1090 }
1091 case 'd':
1092 case 'e':
1093 {
1094 try {
1095 t_day = (*itr == 'd') ?
1096 this->m_parser.parse_day_of_month(sitr, stream_end) :
1097 this->m_parser.parse_var_day_of_month(sitr, stream_end);
1098 }
1099 catch(std::out_of_range&) {
1100 match_results mr;
1101 if(this->m_sv_parser.match(sitr, stream_end, mr)) {
1102 t = time_type(static_cast<special_values>(mr.current_match));
1103 return sitr;
1104 }
1105 else {
1106 throw;
1107 }
1108 }
1109 break;
1110 }
1111
1112 case 'H':
1113 {
1114 match_results mr;
1115 hour = fixed_string_to_int<hour_type, CharT>(sitr, stream_end, mr, 2);
1116 if(hour == -1){
1117 return check_special_value(sitr, stream_end, t, c);
1118 }
1119 break;
1120 }
1121 case 'M':
1122 {
1123 match_results mr;
1124 min = fixed_string_to_int<min_type, CharT>(sitr, stream_end, mr, 2);
1125 if(min == -1){
1126 return check_special_value(sitr, stream_end, t, c);
1127 }
1128 break;
1129 }
1130 case 's':
1131 case 'S':
1132 {
1133 match_results mr;
1134 sec = fixed_string_to_int<sec_type, CharT>(sitr, stream_end, mr, 2);
1135 if(sec == -1){
1136 return check_special_value(sitr, stream_end, t, c);
1137 }
1138 if (*itr == 'S' || sitr == stream_end)
1139 break;
1140
1141
1142 }
1143
1144 case 'f':
1145 {
1146
1147 if(*sitr == '.') {
1148 ++sitr;
1149 parse_frac_type(sitr, stream_end, frac);
1150
1151
1152 use_current_char = true;
1153 }
1154 else {
1155 return check_special_value(sitr, stream_end, t, c);
1156 }
1157 break;
1158 }
1159 case 'F':
1160 {
1161
1162 if(*sitr == '.') {
1163 ++sitr;
1164 parse_frac_type(sitr, stream_end, frac);
1165
1166
1167 use_current_char = true;
1168 }
1169 else {
1170
1171 use_current_char = true;
1172 }
1173 break;
1174 }
1175
1176
1177
1178
1179 case 'Z':
1180 {
1181 if(time_is_local) {
1182 ++itr;
1183 if(*itr == 'P') {
1184
1185 while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; }
1186
1187 while((sitr != stream_end) && (!std::isspace(*sitr))) {
1188 tz_str += *sitr;
1189 ++sitr;
1190 }
1191 }
1192 else {
1193 use_current_format_char = true;
1194 }
1195
1196 }
1197 else {
1198
1199 use_current_char = true;
1200 }
1201
1202 break;
1203 }
1204 default:
1205 {}
1206 }
1207 }
1208 else {
1209 ++sitr;
1210 }
1211
1212 if(use_current_format_char) {
1213 use_current_format_char = false;
1214 }
1215 else {
1216 ++itr;
1217 }
1218
1219 }
1220 else {
1221 ++itr;
1222
1223
1224 if (use_current_char) {
1225 use_current_char = false;
1226 }
1227 else {
1228 ++sitr;
1229 }
1230 }
1231 }
1232
1233 date_type d(not_a_date_time);
1234 if (day_of_year > 0) {
1235 d = date_type(static_cast<unsigned short>(t_year),1,1) + date_duration_type(day_of_year-1);
1236 }
1237 else {
1238 d = date_type(t_year, t_month, t_day);
1239 }
1240
1241 time_duration_type td(hour, min, sec, frac);
1242 t = time_type(d, td);
1243 return sitr;
1244 }
1245
1246
1247
1248
1249
1250 template<class temporal_type>
1251 inline
1252 InItrT check_special_value(InItrT& sitr,InItrT& stream_end, temporal_type& tt, char_type c='\0') const
1253 {
1254 match_results mr;
1255 if((c == '-' || c == '+') && (*sitr != c)) {
1256 mr.cache += c;
1257 }
1258 (void)this->m_sv_parser.match(sitr, stream_end, mr);
1259 if(mr.current_match == match_results::PARSE_ERROR) {
1260 std::string tmp = convert_string_type<char_type, char>(mr.cache);
1261 boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + tmp + "'"));
1262 BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return sitr);
1263 }
1264 tt = temporal_type(static_cast<special_values>(mr.current_match));
1265 return sitr;
1266 }
1267
1268
1269 void parse_frac_type(InItrT& sitr,
1270 InItrT& stream_end,
1271 fracional_seconds_type& frac) const
1272 {
1273 string_type cache;
1274 while((sitr != stream_end) && std::isdigit(*sitr)) {
1275 cache += *sitr;
1276 ++sitr;
1277 }
1278 if(cache.size() > 0) {
1279 unsigned short precision = time_duration_type::num_fractional_digits();
1280
1281 if(cache.size() < precision) {
1282 frac = lexical_cast<fracional_seconds_type>(cache);
1283 frac = decimal_adjust(frac, static_cast<unsigned short>(precision - cache.size()));
1284 }
1285 else {
1286
1287 frac = lexical_cast<fracional_seconds_type>(cache.substr(0, precision));
1288 }
1289 }
1290 }
1291
1292 private:
1293 string_type m_time_duration_format;
1294
1295
1296 template<class int_type>
1297 inline
1298 int_type decimal_adjust(int_type val, const unsigned short places) const
1299 {
1300 unsigned long factor = 1;
1301 for(int i = 0; i < places; ++i){
1302 factor *= 10;
1303 }
1304 return val * factor;
1305 }
1306
1307 };
1308
1309 template <class time_type, class CharT, class InItrT>
1310 std::locale::id time_input_facet<time_type, CharT, InItrT>::id;
1311
1312 template <class time_type, class CharT, class InItrT>
1313 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1314 time_input_facet<time_type, CharT, InItrT>::fractional_seconds_format = time_formats<CharT>::fractional_seconds_format;
1315
1316 template <class time_type, class CharT, class InItrT>
1317 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1318 time_input_facet<time_type, CharT, InItrT>::fractional_seconds_or_none_format = time_formats<CharT>::fractional_seconds_or_none_format;
1319
1320 template <class time_type, class CharT, class InItrT>
1321 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1322 time_input_facet<time_type, CharT, InItrT>::seconds_with_fractional_seconds_format = time_formats<CharT>::seconds_with_fractional_seconds_format;
1323
1324 template <class time_type, class CharT, class InItrT>
1325 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1326 time_input_facet<time_type, CharT, InItrT>::seconds_format = time_formats<CharT>::seconds_format;
1327
1328 template <class time_type, class CharT, class InItrT>
1329 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1330 time_input_facet<time_type, CharT, InItrT>::standard_format = time_formats<CharT>::standard_format;
1331
1332 template <class time_type, class CharT, class InItrT>
1333 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1334 time_input_facet<time_type, CharT, InItrT>::zone_abbrev_format = time_formats<CharT>::zone_abbrev_format;
1335
1336 template <class time_type, class CharT, class InItrT>
1337 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1338 time_input_facet<time_type, CharT, InItrT>::zone_name_format = time_formats<CharT>::zone_name_format;
1339
1340 template <class time_type, class CharT, class InItrT>
1341 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1342 time_input_facet<time_type, CharT, InItrT>::zone_iso_format = time_formats<CharT>::zone_iso_format;
1343
1344 template <class time_type, class CharT, class InItrT>
1345 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1346 time_input_facet<time_type, CharT, InItrT>::zone_iso_extended_format = time_formats<CharT>::zone_iso_extended_format;
1347
1348 template <class time_type, class CharT, class InItrT>
1349 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1350 time_input_facet<time_type, CharT, InItrT>::duration_seperator = time_formats<CharT>::duration_seperator;
1351
1352 template <class time_type, class CharT, class InItrT>
1353 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1354 time_input_facet<time_type, CharT, InItrT>::iso_time_format_specifier = time_formats<CharT>::iso_time_format_specifier;
1355
1356 template <class time_type, class CharT, class InItrT>
1357 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1358 time_input_facet<time_type, CharT, InItrT>::iso_time_format_extended_specifier = time_formats<CharT>::iso_time_format_extended_specifier;
1359
1360 template <class time_type, class CharT, class InItrT>
1361 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1362 time_input_facet<time_type, CharT, InItrT>::default_time_input_format = time_formats<CharT>::default_time_input_format;
1363
1364 template <class time_type, class CharT, class InItrT>
1365 const typename time_input_facet<time_type, CharT, InItrT>::char_type*
1366 time_input_facet<time_type, CharT, InItrT>::default_time_duration_format = time_formats<CharT>::default_time_duration_format;
1367
1368 } }
1369
1370 #endif