web-dev-qa-db-fra.com

Comment imprimer l'heure actuelle (en millisecondes) à l'aide de C++/C++ 11

Actuellement j'utilise ce code

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

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

formater le temps. J'ai besoin d'ajouter des millisecondes pour que la sortie ait le format suivant: 16:56:12.321

19
Prospolon

Vous pouvez utiliser Posost Time de Boost.

Vous pouvez utiliser boost::posix_time::microsec_clock::local_time() pour obtenir l'heure actuelle à partir d'une horloge à résolution en microsecondes:

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

Ensuite, vous pouvez calculer le décalage horaire dans la journée en cours (puisque votre sortie de durée est sous la forme <hours>:<minutes>:<seconds>.<milliseconds>, je suppose qu’ils sont calculés en tant que décalage du jour en cours; s’ils ne le sont pas, n'hésitez pas à utiliser un autre point de départ pour la durée/intervalle de temps):

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

Vous pouvez ensuite utiliser les accesseurs .hours(), .minutes(), .seconds() pour obtenir les valeurs correspondantes.
Malheureusement, il ne semble pas y avoir d'accesseur .milliseconds(), mais il en existe un .total_milliseconds(); vous pouvez donc faire un peu de maths de soustraction pour que les millisecondes restantes soient formatées dans la chaîne.

Ensuite, vous pouvez utiliser sprintf() (ou sprintf()_s si le code non portable VC++ vous intéresse) pour formater ces champs dans une mémoire tampon char brute et envelopper en toute sécurité cette mémoire tampon de chaîne C brute dans une instance robuste et pratique de std::string.

Voir le code commenté ci-dessous pour plus de détails.

La sortie dans la console est quelque chose comme:

11: 43: 52.276


Exemple de 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
    //
    //      ^          ^
    //      |          |
    //      123456789*12
    //      ---------10-     --> 12 chars + \0 --> 13 chars should suffice
    //  
    // 
    char buf[40];
    sprintf(buf, "%02ld:%02ld:%02ld.%03ld", 
        hours, minutes, seconds, milliseconds);

    return buf;
}

int main()
{
    std::cout << now_str() << '\n';    
}

///////////////////////////////////////////////////////////////////////////////
17
Mr.C64

Ne perdez pas votre temps avec Boost (je sais que beaucoup seront offensés par cette déclaration et considèrent cela comme une hérésie). 

Cette discussion contient deux solutions très pratiques qui ne vous obligent pas à vous asservir à des bibliothèques tierces non standard.

C++: obtenir des millisecondes sous Linux - clock () ne semble pas fonctionner correctement

http://linux.die.net/man/3/clock_gettime

Des références à gettimeofday peuvent être trouvées ici à opengroup.org

16
Martin Goff

Vous pouvez utiliser boost::posix_time. Voir cette SO question . Ex:

boost::posix_time::time_duration diff = tick - now;
diff.total_milliseconds();

Pour obtenir l'heure actuelle:

boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::local_time();
// ('tick' and 'now' are of the type of 't1')

Vous pouvez également utiliser le C++ 11 chrono , si vous pouvez utiliser C++ 11. Ex:

int elapsed_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(end-start).count();

Pour obtenir l'heure actuelle (vous avez plusieurs horloges disponibles, voir la doc):

std::chrono::time_point<std::chrono::system_clock> t2;
t2 = std::chrono::system_clock::now();
// ('start' and 'end' are of the type of 't2')

Pour le temps en millisecondes, vous pouvez obtenir la durée entre minuit et l'heure actuelle. Exemple avec std :: chrono :

unsigned int millis_since_midnight()
{
    // current time
    std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();

    // get midnight
    time_t tnow = std::chrono::system_clock::to_time_t(now);
    tm *date = std::localtime(&tnow);
    date->tm_hour = 0;
    date->tm_min = 0;
    date->tm_sec = 0;
    auto midnight = std::chrono::system_clock::from_time_t(std::mktime(date));

    // number of milliseconds between midnight and now, ie current time in millis
    // The same technique can be used for time since Epoch
    return std::chrono::duration_cast<std::chrono::milliseconds>(now - midnight).count();
}
6
Synxis

Je recommanderais d'utiliser Boost.Chrono au lieu de la bibliothèque Boost.Datetime, car Chrono est devenu une partie de C++ 11. Exemples ici

3
Andriy Tylychko

Voici une solution que j'ai trouvée sans utiliser de boost

std::string getCurrentTimestamp()
{
using std::chrono::system_clock;
auto currentTime = std::chrono::system_clock::now();
char buffer[80];

auto transformed = currentTime.time_since_Epoch().count() / 1000000;

auto millis = transformed % 1000;

std::time_t tt;
tt = system_clock::to_time_t ( currentTime );
auto timeinfo = localtime (&tt);
strftime (buffer,80,"%F %H:%M:%S",timeinfo);
sprintf(buffer, "%s:%03d",buffer,(int)millis);

return std::string(buffer);
}
0
Enrico Pintus