3

I'm looking for a concise solution to output a boost::posix_time::time_duration with a precision of milliseconds: There should be exactly 3 fractional-second digits. The default format produces 6 fractional digits (or none, if they are all 0):

#include <boost/date_time.hpp>
#include <iostream>

int main()
{
    // Define some duration in milliseconds:
    int64_t start_msecs((((40 * 60) + 3) * 60 + 2) * 1000 + 1);

    // The same as time_duration:
    boost::posix_time::time_duration start_time =
        boost::posix_time::milliseconds(start_msecs);

    // No suitable format (for MP4Box chapter starts): ////////////////////
    std::cout << "Wrong format: "
        << std::setprecision(3) // <-- No effect!?
        << start_time << std::endl;
    // Output: "Wrong format: 40:03:02.001000"
    // Required format      : 40:03:02.001

    return 0;
}

Using facets and some work arounds, I can get the required output. But that solution only disables the parts of the date-time library I can't get configured to my needs and replaces them with a low level implementation:

#include <boost/date_time.hpp>
#include <iostream>

int main()
{
    // Define some duration in milliseconds:
    int64_t start_msecs((((40 * 60) + 3) * 60 + 2) * 1000 + 1);

    // The same as time_duration:
    boost::posix_time::time_duration start_time =
            boost::posix_time::milliseconds(start_msecs);

    // Define output format without fractional seconds:
    boost::posix_time::time_facet *output_facet =
        new boost::posix_time::time_facet();
    output_facet->time_duration_format("%O:%M:%S");

    // Imbue cout with format for duration output:
    std::cout.imbue(std::locale(std::locale::classic(), output_facet));

    // Only the milliseconds:
    int64_t msecs_only = start_msecs % 1000;

    // Render duration with exactly 3 fractional-second digits: ///////////
    std::cout << "Working: "
        << start_time << "."
        << std::setw(3) << std::right << std::setfill('0')
        << msecs_only << std::endl;
    // Output: "Working: 40:03:02.001"

    return 0;
}

What would be the recommended way to achieve the required output?

  • 1
    Have you looked at this question and the answer to it? http://stackoverflow.com/questions/7589170/boost-formatting-sub-second-precision-time-with-a-time-stamp – Konrad Kleine Jul 01 '14 at 12:56
  • Thank you for pointing me to that question. Unfortunately, it doesn't directly address the formatting of the fractional-second digits. (At one point, it uses `%f` in a format to provide these digits, but the number of digits `%f` provides appears to be hard coded to 6.) – Carsten Scholtes Jul 02 '14 at 07:01
  • I've discovered a bug in the original question: The type of the facet and the function to set its format were wrong. I've fixed this but the problem prevails. – Carsten Scholtes Jul 02 '14 at 07:19

0 Answers0