Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get date and time string accurate to milliseconds in C++ in Linux?

Tags:

c++

date

linux

time

I want to be able to put into a string the local time and date with millisecond resolution like so:

YYYY-MM-DD hh:mm:ss.sss

Seems like a simple thing to do, but I haven't found a simple answer for how to do this. I am writing in C++ and do have access to 11 compiler but am fine using a C solution if it's cleaner. I found a post here with a solution Get both date and time in milliseconds but surely it can't be that difficult given use of standard libraries. I'm probably going to move forward with that type of solution but was hoping to add to the knowledge base by asking the question here on SO.

I know this will work but again, seems unnecessarily difficult:

#include <sys/time.h>
#include <stdio.h>

int main(void)
{
    string sTimestamp;
    char acTimestamp[256];

    struct timeval tv;
    struct tm *tm;

    gettimeofday(&tv, NULL);

    tm = localtime(&tv.tv_sec);

    sprintf(acTimestamp, "%04d-%02d-%02d %02d:%02d:%02d.%03d\n",
            tm->tm_year + 1900,
            tm->tm_mon + 1,
            tm->tm_mday,
            tm->tm_hour,
            tm->tm_min,
            tm->tm_sec,
            (int) (tv.tv_usec / 1000)
        );

    sTimestamp = acTimestamp;

    cout << sTimestamp << endl;

    return 0;
}

Tried looking at put_time for C++ and strftime for the old C way. Both only allow me to get to second resolution best I can tell. You can see the two approaches I've gotten so far below. I would like to put it into a string

auto t = std::time(nullptr);
auto tm = *std::localtime(&t);
std::cout << std::put_time(&tm, "%Y-%m-%d %H:%M:%S") << std::endl;

time_t rawtime;
struct tm * timeinfo;
char buffer[80];

time (&rawtime);
timeinfo = localtime(&rawtime);

strftime(buffer,sizeof(buffer),"%Y-%m-%d %I:%M:%S",timeinfo);
std::string str(buffer);

std::cout << str;

Only thing I can figure out is to use gettimeofday and get rid of all the data except the last second and append it to the timestamp, still wish there was a cleaner approach.

Anyone find a solution that works better?

like image 707
Brian Avatar asked Mar 16 '17 14:03

Brian


People also ask

How to get time in milliseconds in Linux?

date +"%T. %6N" returns the current time with nanoseconds rounded to the first 6 digits, which is microseconds. date +"%T. %3N" returns the current time with nanoseconds rounded to the first 3 digits, which is milliseconds.

Which function returns the time difference in milliseconds?

Which function returns the time difference in milliseconds? You can use DiffSeconds() built-in function and multiply the result by 1000. The output will be milliseconds.

How do you timestamp in microseconds?

The microtime() function is an inbuilt function in PHP which is used to return the current Unix timestamp with microseconds. The $get_as_float is sent as a parameter to the microtime() function and it returns the string microsec sec by default.


1 Answers

I would recommend looking at Howard Hinnant's date library. One of the examples given in the wiki shows how to get the current local time, up to the given precision of your std::chrono::system_clock implementation (nanoseconds on Linux, from memory?):

EDIT: As Howard points out in the comments, you can use date::floor() to obtain the desired precision. So to generate a string as requested in the question, you could do something like this:

#include "tz.h"
#include <iostream>
#include <string>
#include <sstream>

std::string current_time()
{
    const auto now_ms = date::floor<std::chrono::milliseconds>(std::chrono::system_clock::now());
    std::stringstream ss;
    ss << date::make_zoned(date::current_zone(), now_ms);
    return ss.str();
}

int main()
{
    std::cout << current_time() << '\n';
} 
like image 73
Tristan Brindle Avatar answered Sep 16 '22 23:09

Tristan Brindle