Search code examples
c++boostboost-date-time

How do you format with Boost.Date_Time without leading zeros?


How can you format a boost::posix_time::ptime object without padding the numbers with zeros?

For example, I want to display 6/7/2011 6:30:25 PM and not 06/07/2011 06:30:25 PM.

In .NET, the format string would be something like "m/d/yyyy h:mm:ss tt".

Here is some code to do it the wrong way, just to get an idea:

boost::gregorian::date baseDate(1970, 1, 1);
boost::posix_time::ptime shiftDate(baseDate);
boost::posix_time::time_facet *facet = new time_facet("%m/%d/%Y");
cout.imbue(locale(cout.getloc(), facet));
cout << shiftDate;
delete facet;

Output: 01/01/1970

Solution

  • To my knowledge this capability is not built into Boost.DateTime, but it's pretty trivial to write your own formatting functions, e.g.:

    template<typename CharT, typename TraitsT>
    std::basic_ostream<CharT, TraitsT>& print_date(
        std::basic_ostream<CharT, TraitsT>& os,
        boost::posix_time::ptime const& pt)
    {
        boost::gregorian::date const& d = pt.date();
        return os
            << d.month().as_number() << '/'
            << d.day().as_number() << '/'
            << d.year();
    }
    
    template<typename CharT, typename TraitsT>
    std::basic_ostream<CharT, TraitsT>& print_date_time(
        std::basic_ostream<CharT, TraitsT>& os,
        boost::posix_time::ptime const& pt)
    {
        boost::gregorian::date const& d = pt.date();
        boost::posix_time::time_duration const& t = pt.time_of_day();
        CharT const orig_fill(os.fill('0'));
        os
            << d.month().as_number() << '/'
            << d.day().as_number() << '/'
            << d.year() << ' '
            << (t.hours() && t.hours() != 12 ? t.hours() % 12 : 12) << ':'
            << std::setw(2) << t.minutes() << ':'
            << std::setw(2) << t.seconds() << ' '
            << (t.hours() / 12 ? 'P' : 'A') << 'M';
        os.fill(orig_fill);
        return os;
    }