[Boost-bugs] [Boost C++ Libraries] #11201: setting boost::posix_time::time_facet has no effect on boost::log sinks

Subject: [Boost-bugs] [Boost C++ Libraries] #11201: setting boost::posix_time::time_facet has no effect on boost::log sinks
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-04-18 13:21:32


#11201: setting boost::posix_time::time_facet has no effect on boost::log sinks
-------------------------------------+---------------------
 Reporter: Georg Sauthoff <mail@…> | Owner: andysem
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: log
  Version: Boost Development Trunk | Severity: Problem
 Keywords: |
-------------------------------------+---------------------
 How to reproduce:


 {{{
 #include <boost/date_time/posix_time/posix_time.hpp>

 #include <boost/log/trivial.hpp>
 #include <boost/log/core.hpp>
 #include <boost/log/expressions.hpp>

 #include <boost/log/utility/setup/console.hpp>
 #include <boost/log/attributes.hpp>

 #include <locale>

 int main(int argc, char **argv)
 {
   auto clog = boost::log::add_console_log();
   clog->set_formatter(
         boost::log::expressions::stream
           << "[" << boost::log::trivial::severity << "] "
           << boost::log::expressions::smessage
       );

   const char date_format[] = "%Y-%m-%d %H:%M:%S";
   // does not work
   clog->imbue(std::locale(clog->getloc(),
     new boost::posix_time::time_facet(date_format)
         ));

   boost::posix_time::ptime dt(
       boost::gregorian::date(2015, 1, 1),
       boost::posix_time::time_duration(8, 48, 0)
       );
   BOOST_LOG_TRIVIAL(info) << dt;
   BOOST_LOG_TRIVIAL(info) << dt;

   return 0;
 }
 }}}

 Expected output:

 {{{
 $ ./test_log_datetime
 [info] 2015-01-01 08:48:00
 [info] 2015-01-01 08:48:00
 }}}

 Actual output:

 {{{
 $ ./test_log_datetime
 [info] 2015-Jan-01 08:48:00
 [info] 2015-Jan-01 08:48:00
 }}}


 When stepping through the code I observe that the output operator in
 {{{boost/posix_time/posix_time_io.hpp}}}

 {{{
   operator<<(std::basic_ostream<CharT, TraitsT>& os,
              const boost::posix_time::time_period& p) {
     boost::io::ios_flags_saver iflags(os);
     typedef boost::date_time::time_facet<ptime, CharT> custom_ptime_facet;
     std::ostreambuf_iterator<CharT> oitr(os);
     if (std::has_facet<custom_ptime_facet>(os.getloc())) {
       std::use_facet<custom_ptime_facet>(os.getloc()).put(oitr, os,
 os.fill(), p);
     }
     else {
       //instantiate a custom facet for dealing with periods since the user
       //has not put one in the stream so far. This is for efficiency
       //since we would always need to reconstruct for every time period
       //if the local did not already exist. Of course this will be
 overridden
       //if the user imbues as some later point.
       custom_ptime_facet* f = new custom_ptime_facet();
       std::locale l = std::locale(os.getloc(), f);
       os.imbue(l);
       f->put(oitr, os, os.fill(), p);
     }
     return os;
 }}}

 is executed 2 times - as expected - but the condition is both times false.
 Expected behaviour: both times true, or at least: first time false and 2nd
 time true.


 Even when not trying to set a custom facet:

 {{{
 #include <boost/date_time/posix_time/posix_time.hpp>

 #include <boost/log/trivial.hpp>


 int main(int argc, char **argv)
 {
   boost::posix_time::ptime dt(
       boost::gregorian::date(2015, 1, 1),
       boost::posix_time::time_duration(8, 48, 0)
       );
   BOOST_LOG_TRIVIAL(info) << dt;
   BOOST_LOG_TRIVIAL(info) << dt;

   return 0;
 }
 }}}

 the debugger shows that the default facet is instantiated 2 times in
 {{{boost/posix_time/posix_time_io.hpp}}} (i.e. condition is both times
 false).


 When not using Boost Log, setting the facet works as expected:

 {{{
 #include <boost/date_time/posix_time/posix_time.hpp>

 #include <iostream>
 #include <locale>

 int main(int argc, char **argv)
 {
   const char date_format[] = "%Y-%m-%d %H:%M:%S";
   std::clog.imbue(std::locale(std::clog.getloc(),
       new boost::posix_time::time_facet(date_format)
           ));

   boost::posix_time::ptime dt(
       boost::gregorian::date(2015, 1, 1),
       boost::posix_time::time_duration(8, 48, 0)
       );
   std::clog << dt << '\n';
   std::clog << dt << '\n';

   return 0;
 }
 }}}

 Output:

 {{{
 2015-01-01 08:48:00
 2015-01-01 08:48:00
 }}}

 The debugger shows that the condition in the output operator in
 {{{boost/posix_time/posix_time_io.hpp}}} is both times true, as expected.

 Also as expected, when commenting out the {{{clog.imbue()}}} call, the
 condition is the first time false, and the second time true.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11201>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC