Boost C++ Libraries: Ticket #11201: setting boost::posix_time::time_facet has no effect on boost::log sinks https://svn.boost.org/trac10/ticket/11201 <p> How to reproduce: </p> <pre class="wiki">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; #include &lt;boost/log/trivial.hpp&gt; #include &lt;boost/log/core.hpp&gt; #include &lt;boost/log/expressions.hpp&gt; #include &lt;boost/log/utility/setup/console.hpp&gt; #include &lt;boost/log/attributes.hpp&gt; #include &lt;locale&gt; int main(int argc, char **argv) { auto clog = boost::log::add_console_log(); clog-&gt;set_formatter( boost::log::expressions::stream &lt;&lt; "[" &lt;&lt; boost::log::trivial::severity &lt;&lt; "] " &lt;&lt; boost::log::expressions::smessage ); const char date_format[] = "%Y-%m-%d %H:%M:%S"; // does not work clog-&gt;imbue(std::locale(clog-&gt;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) &lt;&lt; dt; BOOST_LOG_TRIVIAL(info) &lt;&lt; dt; return 0; } </pre><p> Expected output: </p> <pre class="wiki">$ ./test_log_datetime [info] 2015-01-01 08:48:00 [info] 2015-01-01 08:48:00 </pre><p> Actual output: </p> <pre class="wiki">$ ./test_log_datetime [info] 2015-Jan-01 08:48:00 [info] 2015-Jan-01 08:48:00 </pre><p> When stepping through the code I observe that the output operator in <code>boost/posix_time/posix_time_io.hpp</code> </p> <pre class="wiki"> operator&lt;&lt;(std::basic_ostream&lt;CharT, TraitsT&gt;&amp; os, const boost::posix_time::time_period&amp; p) { boost::io::ios_flags_saver iflags(os); typedef boost::date_time::time_facet&lt;ptime, CharT&gt; custom_ptime_facet; std::ostreambuf_iterator&lt;CharT&gt; oitr(os); if (std::has_facet&lt;custom_ptime_facet&gt;(os.getloc())) { std::use_facet&lt;custom_ptime_facet&gt;(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-&gt;put(oitr, os, os.fill(), p); } return os; </pre><p> 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. </p> <p> Even when not trying to set a custom facet: </p> <pre class="wiki">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; #include &lt;boost/log/trivial.hpp&gt; 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) &lt;&lt; dt; BOOST_LOG_TRIVIAL(info) &lt;&lt; dt; return 0; } </pre><p> the debugger shows that the default facet is instantiated 2 times in <code>boost/posix_time/posix_time_io.hpp</code> (i.e. condition is both times false). </p> <p> When not using Boost Log, setting the facet works as expected: </p> <pre class="wiki">#include &lt;boost/date_time/posix_time/posix_time.hpp&gt; #include &lt;iostream&gt; #include &lt;locale&gt; 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 &lt;&lt; dt &lt;&lt; '\n'; std::clog &lt;&lt; dt &lt;&lt; '\n'; return 0; } </pre><p> Output: </p> <pre class="wiki">2015-01-01 08:48:00 2015-01-01 08:48:00 </pre><p> The debugger shows that the condition in the output operator in <code>boost/posix_time/posix_time_io.hpp</code> is both times true, as expected. </p> <p> Also as expected, when commenting out the <code>clog.imbue()</code> call, the condition is the first time false, and the second time true. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11201 Trac 1.4.3 Andrey Semashev Sat, 25 Apr 2015 20:36:42 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/11201#comment:1 https://svn.boost.org/trac10/ticket/11201#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> The locale you imbue into the sink is used by the formatter (the function object you pass to set_formatter). It has no effect on the log message formatting. In fact, the message comes to the formatter as a string already. </p> <p> The message text is formatted by a separate stream with its own locale. That stream is not publicly accessible, except though the logging macros. The locale it uses is the default constructed and does not contain Boost.<a class="missing wiki">DateTime</a> facets. This is so because the message text is formatted only once while there can be multiple sinks with different formatters and different locales. </p> <p> If you want the message formatting stream to use Boost.<a class="missing wiki">DateTime</a> facets you can add the facet to the global locale before you start using Boost.Log. This should typically be done somewhere in the application startup code. </p> Ticket