Search code examples
c++linuxwindowstimec++11

How to print current time (with milliseconds) using C++ / C++11


Currently I use this code

string now() {
    time_t t = time(0);
    char buffer[9] = {0};

    strftime(buffer, 9, "%H:%M:%S", localtime(&t));
    return string(buffer);
}

to format time. I need to add milliseconds, so the output has the format: 16:56:12.321


Solution

  • You can use Boost's Posix Time.

    You can use boost::posix_time::microsec_clock::local_time() to get current time from microseconds-resolution clock:

    boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
    

    Then you can compute time offset in current day (since your duration output is in the form <hours>:<minutes>:<seconds>.<milliseconds>, I'm assuming they are calculated as current day offset; if they are not, feel free to use another starting point for duration/time interval):

    boost::posix_time::time_duration td = now.time_of_day();
    

    Then you can use .hours(), .minutes(), .seconds() accessors to get the corresponding values.
    Unfortunately, there doesn't seem to be a .milliseconds() accessor, but there is a .total_milliseconds() one; so you can do a little subtraction math to get the remaining milliseconds to be formatted in the string.

    Then you can use sprintf() (or sprintf()_s if you are interested in non-portable VC++-only code) to format those fields into a raw char buffer, and safely wrap this raw C string buffer into a robust convenient std::string instance.

    See the commented code below for further details.

    Output in console is something like:

    11:43:52.276


    Sample code:

    ///////////////////////////////////////////////////////////////////////////////
    
    #include <stdio.h>      // for sprintf()
    
    #include <iostream>     // for console output
    #include <string>       // for std::string
    
    #include <boost/date_time/posix_time/posix_time.hpp>
    
    
    //-----------------------------------------------------------------------------
    // Format current time (calculated as an offset in current day) in this form:
    //
    //     "hh:mm:ss.SSS" (where "SSS" are milliseconds)
    //-----------------------------------------------------------------------------
    std::string now_str()
    {
        // Get current time from the clock, using microseconds resolution
        const boost::posix_time::ptime now = 
            boost::posix_time::microsec_clock::local_time();
        
        // Get the time offset in current day
        const boost::posix_time::time_duration td = now.time_of_day();
        
        //
        // Extract hours, minutes, seconds and milliseconds.
        //
        // Since there is no direct accessor ".milliseconds()",
        // milliseconds are computed _by difference_ between total milliseconds
        // (for which there is an accessor), and the hours/minutes/seconds
        // values previously fetched.
        //
        const long hours        = td.hours();
        const long minutes      = td.minutes();
        const long seconds      = td.seconds();
        const long milliseconds = td.total_milliseconds() -
                                  ((hours * 3600 + minutes * 60 + seconds) * 1000);
        
        //
        // Format like this:
        //
        //      hh:mm:ss.SSS
        //
        // e.g. 02:15:40.321
        // 
        char buf[] = "hh:mm:ss.SSS";
        sprintf_s(buf, "%02ld:%02ld:%02ld.%03ld", 
            hours, minutes, seconds, milliseconds);
        
        return buf;
    }
    
    int main()
    {
        std::cout << now_str() << '\n';    
    }
    
    ///////////////////////////////////////////////////////////////////////////////