File indexing completed on 2025-01-30 09:45:08
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef BOOST_LOG_SUPPORT_DATE_TIME_HPP_INCLUDED_
0016 #define BOOST_LOG_SUPPORT_DATE_TIME_HPP_INCLUDED_
0017
0018 #include <ctime>
0019 #include <string>
0020 #include <locale>
0021 #include <ostream>
0022 #include <iterator>
0023 #include <boost/cstdint.hpp>
0024 #include <boost/move/core.hpp>
0025 #include <boost/move/utility_core.hpp>
0026 #include <boost/date_time/time.hpp>
0027 #include <boost/date_time/date.hpp>
0028 #include <boost/date_time/gregorian/gregorian_types.hpp>
0029 #include <boost/date_time/local_time/local_time_types.hpp>
0030 #include <boost/date_time/posix_time/posix_time_types.hpp>
0031 #include <boost/log/detail/config.hpp>
0032 #include <boost/log/detail/date_time_format_parser.hpp>
0033 #include <boost/log/detail/light_function.hpp>
0034 #include <boost/log/detail/decomposed_time.hpp>
0035 #include <boost/log/detail/date_time_fmt_gen_traits_fwd.hpp>
0036 #include <boost/log/utility/formatting_ostream.hpp>
0037 #include <boost/log/detail/header.hpp>
0038
0039 #ifdef BOOST_HAS_PRAGMA_ONCE
0040 #pragma once
0041 #endif
0042
0043 namespace boost {
0044
0045 BOOST_LOG_OPEN_NAMESPACE
0046
0047 namespace expressions {
0048
0049 namespace aux {
0050
0051 namespace date_time_support {
0052
0053 template< typename DateT, typename ValueT >
0054 inline void decompose_date(DateT const& d, boost::log::aux::decomposed_time_wrapper< ValueT >& v)
0055 {
0056 typedef typename DateT::ymd_type ymd_type;
0057 ymd_type ymd = d.year_month_day();
0058 v.year = static_cast< uint32_t >(ymd.year);
0059 v.month = static_cast< uint32_t >(ymd.month);
0060 v.day = static_cast< uint32_t >(ymd.day);
0061 }
0062
0063 template< typename TimeDurationT, typename ValueT >
0064 inline void decompose_time_of_day(TimeDurationT const& tod, boost::log::aux::decomposed_time_wrapper< ValueT >& v)
0065 {
0066 v.hours = static_cast< uint32_t >(tod.hours());
0067 v.minutes = static_cast< uint32_t >(tod.minutes());
0068 v.seconds = static_cast< uint32_t >(tod.seconds());
0069
0070 typedef typename TimeDurationT::traits_type traits_type;
0071 enum
0072 {
0073 adjustment_ratio = (traits_type::ticks_per_second > boost::log::aux::decomposed_time::subseconds_per_second ?
0074 traits_type::ticks_per_second / boost::log::aux::decomposed_time::subseconds_per_second :
0075 boost::log::aux::decomposed_time::subseconds_per_second / traits_type::ticks_per_second)
0076 };
0077 uint64_t frac = tod.fractional_seconds();
0078 v.subseconds = static_cast< uint32_t >(traits_type::ticks_per_second > boost::log::aux::decomposed_time::subseconds_per_second ? frac / adjustment_ratio : frac * adjustment_ratio);
0079 }
0080
0081 template< typename TimeDurationT, typename ValueT >
0082 inline void decompose_time_duration(TimeDurationT const& dur, boost::log::aux::decomposed_time_wrapper< ValueT >& v)
0083 {
0084 if (dur.is_negative())
0085 {
0086 v.negative = true;
0087 (decompose_time_of_day)(-dur, v);
0088 }
0089 else
0090 (decompose_time_of_day)(dur, v);
0091 }
0092
0093 template< typename DateDurationT, typename ValueT >
0094 inline void decompose_date_duration(DateDurationT const& dur, boost::log::aux::decomposed_time_wrapper< ValueT >& v)
0095 {
0096 if (dur.is_negative())
0097 {
0098 v.negative = true;
0099 v.day = static_cast< uint32_t >((-dur).days());
0100 }
0101 else
0102 v.day = static_cast< uint32_t >(dur.days());
0103 }
0104
0105 template< typename TimeT, typename ValueT >
0106 inline void decompose_time(TimeT const& t, boost::log::aux::decomposed_time_wrapper< ValueT >& v)
0107 {
0108 (decompose_date)(t.date(), v);
0109 (decompose_time_of_day)(t.time_of_day(), v);
0110 }
0111
0112 }
0113
0114 template< typename TimeT, typename CharT >
0115 struct date_time_formatter_generator_traits_impl
0116 {
0117
0118 typedef CharT char_type;
0119
0120 typedef std::basic_string< char_type > string_type;
0121
0122 typedef basic_formatting_ostream< char_type > stream_type;
0123
0124 typedef TimeT value_type;
0125
0126
0127 typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
0128
0129
0130 class formatter :
0131 public boost::log::aux::date_time_formatter< boost::log::aux::decomposed_time_wrapper< value_type >, char_type >
0132 {
0133 BOOST_COPYABLE_AND_MOVABLE_ALT(formatter)
0134
0135 private:
0136
0137 typedef typename formatter::date_time_formatter_ base_type;
0138
0139 public:
0140 typedef typename base_type::result_type result_type;
0141
0142 typedef typename date_time_formatter_generator_traits_impl< TimeT, CharT >::value_type value_type;
0143
0144 public:
0145 BOOST_DEFAULTED_FUNCTION(formatter(), {})
0146 formatter(formatter const& that) : base_type(static_cast< base_type const& >(that)) {}
0147 formatter(BOOST_RV_REF(formatter) that) { this->swap(that); }
0148
0149 formatter& operator= (formatter that)
0150 {
0151 this->swap(that);
0152 return *this;
0153 }
0154
0155 result_type operator() (stream_type& strm, value_type const& value) const
0156 {
0157 if (value.is_not_a_date_time())
0158 strm << "not-a-date-time";
0159 else if (value.is_pos_infinity())
0160 strm << "+infinity";
0161 else if (value.is_neg_infinity())
0162 strm << "-infinity";
0163 else
0164 {
0165 boost::log::aux::decomposed_time_wrapper< value_type > val(value);
0166 date_time_support::decompose_time(value, val);
0167 base_type::operator() (strm, val);
0168 }
0169 }
0170 };
0171
0172
0173 static formatter_function_type parse(string_type const& format)
0174 {
0175 formatter fmt;
0176 boost::log::aux::decomposed_time_formatter_builder< formatter, char_type > builder(fmt);
0177 boost::log::aux::parse_date_time_format(format, builder);
0178 return formatter_function_type(boost::move(fmt));
0179 }
0180 };
0181
0182 template< typename CharT, typename VoidT >
0183 struct date_time_formatter_generator_traits< posix_time::ptime, CharT, VoidT > :
0184 public date_time_formatter_generator_traits_impl< posix_time::ptime, CharT >
0185 {
0186 };
0187
0188 template< typename TimeT, typename TimeZoneT, typename CharT, typename VoidT >
0189 struct date_time_formatter_generator_traits< local_time::local_date_time_base< TimeT, TimeZoneT >, CharT, VoidT >
0190 {
0191
0192 typedef CharT char_type;
0193
0194 typedef std::basic_string< char_type > string_type;
0195
0196 typedef basic_formatting_ostream< char_type > stream_type;
0197
0198 typedef local_time::local_date_time_base< TimeT, TimeZoneT > value_type;
0199
0200
0201 typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
0202
0203
0204 class formatter :
0205 public boost::log::aux::date_time_formatter< boost::log::aux::decomposed_time_wrapper< value_type >, char_type >
0206 {
0207 BOOST_COPYABLE_AND_MOVABLE_ALT(formatter)
0208
0209 private:
0210
0211 typedef typename formatter::date_time_formatter_ base_type;
0212
0213 public:
0214 typedef typename base_type::result_type result_type;
0215 typedef typename base_type::context context;
0216
0217 typedef typename date_time_formatter_generator_traits< local_time::local_date_time_base< TimeT, TimeZoneT >, CharT, VoidT >::value_type value_type;
0218
0219 public:
0220 BOOST_DEFAULTED_FUNCTION(formatter(), {})
0221 formatter(formatter const& that) : base_type(static_cast< base_type const& >(that)) {}
0222 formatter(BOOST_RV_REF(formatter) that) { this->swap(that); }
0223
0224 formatter& operator= (formatter that)
0225 {
0226 this->swap(that);
0227 return *this;
0228 }
0229
0230 result_type operator() (stream_type& strm, value_type const& value) const
0231 {
0232 if (value.is_not_a_date_time())
0233 strm << "not-a-date-time";
0234 else if (value.is_pos_infinity())
0235 strm << "+infinity";
0236 else if (value.is_neg_infinity())
0237 strm << "-infinity";
0238 else
0239 {
0240 boost::log::aux::decomposed_time_wrapper< value_type > val(value);
0241 date_time_support::decompose_time(value.local_time(), val);
0242 base_type::operator() (strm, val);
0243 }
0244 }
0245
0246 public:
0247 static void format_iso_time_zone(context& ctx)
0248 {
0249 ctx.strm << ctx.value.m_time.zone_abbrev(true);
0250 ctx.strm.flush();
0251 }
0252
0253 static void format_extended_iso_time_zone(context& ctx)
0254 {
0255 ctx.strm << ctx.value.m_time.zone_name(true);
0256 ctx.strm.flush();
0257 }
0258 };
0259
0260 class formatter_builder :
0261 public boost::log::aux::decomposed_time_formatter_builder< formatter, char_type >
0262 {
0263 private:
0264 typedef boost::log::aux::decomposed_time_formatter_builder< formatter, char_type > base_type;
0265
0266 public:
0267 explicit formatter_builder(formatter& fmt) : base_type(fmt)
0268 {
0269 }
0270
0271 void on_iso_time_zone()
0272 {
0273 this->m_formatter.add_formatter(&formatter::format_iso_time_zone);
0274 }
0275
0276 void on_extended_iso_time_zone()
0277 {
0278 this->m_formatter.add_formatter(&formatter::format_extended_iso_time_zone);
0279 }
0280 };
0281
0282
0283 static formatter_function_type parse(string_type const& format)
0284 {
0285 formatter fmt;
0286 formatter_builder builder(fmt);
0287 boost::log::aux::parse_date_time_format(format, builder);
0288 return formatter_function_type(boost::move(fmt));
0289 }
0290 };
0291
0292 template< typename DateT, typename CharT >
0293 struct date_formatter_generator_traits_impl
0294 {
0295
0296 typedef CharT char_type;
0297
0298 typedef std::basic_string< char_type > string_type;
0299
0300 typedef basic_formatting_ostream< char_type > stream_type;
0301
0302 typedef DateT value_type;
0303
0304
0305 typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
0306
0307
0308 class formatter :
0309 public boost::log::aux::date_time_formatter< boost::log::aux::decomposed_time_wrapper< value_type >, char_type >
0310 {
0311 BOOST_COPYABLE_AND_MOVABLE_ALT(formatter)
0312
0313 private:
0314
0315 typedef typename formatter::date_time_formatter_ base_type;
0316
0317 public:
0318 typedef typename base_type::result_type result_type;
0319
0320 typedef typename date_formatter_generator_traits_impl< DateT, CharT >::value_type value_type;
0321
0322 public:
0323 BOOST_DEFAULTED_FUNCTION(formatter(), {})
0324 formatter(formatter const& that) : base_type(static_cast< base_type const& >(that)) {}
0325 formatter(BOOST_RV_REF(formatter) that) { this->swap(that); }
0326
0327 formatter& operator= (formatter that)
0328 {
0329 this->swap(that);
0330 return *this;
0331 }
0332
0333 result_type operator() (stream_type& strm, value_type const& value) const
0334 {
0335 if (value.is_not_a_date())
0336 strm << "not-a-date-time";
0337 else if (value.is_pos_infinity())
0338 strm << "+infinity";
0339 else if (value.is_neg_infinity())
0340 strm << "-infinity";
0341 else
0342 {
0343 boost::log::aux::decomposed_time_wrapper< value_type > val(value);
0344 date_time_support::decompose_date(value, val);
0345 base_type::operator() (strm, val);
0346 }
0347 }
0348 };
0349
0350
0351 static formatter_function_type parse(string_type const& format)
0352 {
0353 formatter fmt;
0354 boost::log::aux::decomposed_time_formatter_builder< formatter, char_type > builder(fmt);
0355 boost::log::aux::parse_date_format(format, builder);
0356 return formatter_function_type(boost::move(fmt));
0357 }
0358 };
0359
0360 template< typename CharT, typename VoidT >
0361 struct date_time_formatter_generator_traits< gregorian::date, CharT, VoidT > :
0362 public date_formatter_generator_traits_impl< gregorian::date, CharT >
0363 {
0364 };
0365
0366 template< typename TimeDurationT, typename CharT >
0367 struct time_duration_formatter_generator_traits_impl
0368 {
0369
0370 typedef CharT char_type;
0371
0372 typedef std::basic_string< char_type > string_type;
0373
0374 typedef basic_formatting_ostream< char_type > stream_type;
0375
0376 typedef TimeDurationT value_type;
0377
0378
0379 typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
0380
0381
0382 class formatter :
0383 public boost::log::aux::date_time_formatter< boost::log::aux::decomposed_time_wrapper< value_type >, char_type >
0384 {
0385 BOOST_COPYABLE_AND_MOVABLE_ALT(formatter)
0386
0387 private:
0388
0389 typedef typename formatter::date_time_formatter_ base_type;
0390
0391 public:
0392 typedef typename base_type::result_type result_type;
0393
0394 typedef typename time_duration_formatter_generator_traits_impl< TimeDurationT, CharT >::value_type value_type;
0395
0396 public:
0397 BOOST_DEFAULTED_FUNCTION(formatter(), {})
0398 formatter(formatter const& that) : base_type(static_cast< base_type const& >(that)) {}
0399 formatter(BOOST_RV_REF(formatter) that) { this->swap(that); }
0400
0401 formatter& operator= (formatter that)
0402 {
0403 this->swap(that);
0404 return *this;
0405 }
0406
0407 result_type operator() (stream_type& strm, value_type const& value) const
0408 {
0409 if (value.is_not_a_date_time())
0410 strm << "not-a-date-time";
0411 else if (value.is_pos_infinity())
0412 strm << "+infinity";
0413 else if (value.is_neg_infinity())
0414 strm << "-infinity";
0415 else
0416 {
0417 boost::log::aux::decomposed_time_wrapper< value_type > val(value);
0418 date_time_support::decompose_time_duration(value, val);
0419 base_type::operator() (strm, val);
0420 }
0421 }
0422 };
0423
0424
0425 static formatter_function_type parse(string_type const& format)
0426 {
0427 formatter fmt;
0428 boost::log::aux::decomposed_time_formatter_builder< formatter, char_type > builder(fmt);
0429 boost::log::aux::parse_time_format(format, builder);
0430 return formatter_function_type(boost::move(fmt));
0431 }
0432 };
0433
0434 template< typename CharT, typename VoidT >
0435 struct date_time_formatter_generator_traits< posix_time::time_duration, CharT, VoidT > :
0436 public time_duration_formatter_generator_traits_impl< posix_time::time_duration, CharT >
0437 {
0438 };
0439
0440 template< typename CharT, typename VoidT >
0441 struct date_time_formatter_generator_traits< posix_time::hours, CharT, VoidT > :
0442 public time_duration_formatter_generator_traits_impl< posix_time::hours, CharT >
0443 {
0444 };
0445
0446 template< typename CharT, typename VoidT >
0447 struct date_time_formatter_generator_traits< posix_time::minutes, CharT, VoidT > :
0448 public time_duration_formatter_generator_traits_impl< posix_time::minutes, CharT >
0449 {
0450 };
0451
0452 template< typename CharT, typename VoidT >
0453 struct date_time_formatter_generator_traits< posix_time::seconds, CharT, VoidT > :
0454 public time_duration_formatter_generator_traits_impl< posix_time::seconds, CharT >
0455 {
0456 };
0457
0458 template< typename BaseDurationT, uint64_t FracOfSecondV, typename CharT, typename VoidT >
0459 struct date_time_formatter_generator_traits< date_time::subsecond_duration< BaseDurationT, FracOfSecondV >, CharT, VoidT > :
0460 public time_duration_formatter_generator_traits_impl< date_time::subsecond_duration< BaseDurationT, FracOfSecondV >, CharT >
0461 {
0462 };
0463
0464 template< typename DateDurationT, typename CharT >
0465 struct date_duration_formatter_generator_traits_impl
0466 {
0467
0468 typedef CharT char_type;
0469
0470 typedef std::basic_string< char_type > string_type;
0471
0472 typedef basic_formatting_ostream< char_type > stream_type;
0473
0474 typedef DateDurationT value_type;
0475
0476
0477 typedef boost::log::aux::light_function< void (stream_type&, value_type const&) > formatter_function_type;
0478
0479
0480 class formatter :
0481 public boost::log::aux::date_time_formatter< boost::log::aux::decomposed_time_wrapper< value_type >, char_type >
0482 {
0483 BOOST_COPYABLE_AND_MOVABLE_ALT(formatter)
0484
0485 private:
0486
0487 typedef typename formatter::date_time_formatter_ base_type;
0488
0489 public:
0490 typedef typename base_type::result_type result_type;
0491
0492 typedef typename date_duration_formatter_generator_traits_impl< DateDurationT, CharT >::value_type value_type;
0493
0494 public:
0495 BOOST_DEFAULTED_FUNCTION(formatter(), {})
0496 formatter(formatter const& that) : base_type(static_cast< base_type const& >(that)) {}
0497 formatter(BOOST_RV_REF(formatter) that) { this->swap(that); }
0498
0499 formatter& operator= (formatter that)
0500 {
0501 this->swap(that);
0502 return *this;
0503 }
0504
0505 result_type operator() (stream_type& strm, value_type const& value) const
0506 {
0507 if (value.is_not_a_date())
0508 strm << "not-a-date-time";
0509 else if (value.is_pos_infinity())
0510 strm << "+infinity";
0511 else if (value.is_neg_infinity())
0512 strm << "-infinity";
0513 else
0514 {
0515 boost::log::aux::decomposed_time_wrapper< value_type > val(value);
0516 date_time_support::decompose_date_duration(value, val);
0517 base_type::operator() (strm, val);
0518 }
0519 }
0520 };
0521
0522
0523 static formatter_function_type parse(string_type const& format)
0524 {
0525 formatter fmt;
0526 boost::log::aux::decomposed_time_formatter_builder< formatter, char_type > builder(fmt);
0527 boost::log::aux::parse_date_format(format, builder);
0528 return formatter_function_type(boost::move(fmt));
0529 }
0530 };
0531
0532 template< typename CharT, typename VoidT >
0533 struct date_time_formatter_generator_traits< gregorian::date_duration, CharT, VoidT > :
0534 public date_formatter_generator_traits_impl< gregorian::date_duration, CharT >
0535 {
0536 };
0537
0538 }
0539
0540 }
0541
0542 BOOST_LOG_CLOSE_NAMESPACE
0543
0544 }
0545
0546 #include <boost/log/detail/footer.hpp>
0547
0548 #endif