ziggy
ziggy

Reputation: 127

How do you print the current system time with milliseconds in C++11?

I've got a problem with getting actual system time with milliseconds. The only one good method I found is in Windows.h, but I can't use it. I'm supposed to use std::chrono. How can I do this?

I spent a lot of time trying to google it, but I found only second-precision examples.

I'm trying to get string like this:

[2014-11-25 22:15:38:449]

Upvotes: 11

Views: 22809

Answers (4)

mbc
mbc

Reputation: 1

Did anybody notice that to_time_t rounds the seconds, instead of truncating

auto now = system_clock::now();
time_t secs = system_clock::to_time_t(now);
now {_MyDur={_MyRep=15107091978759765 } }
secs = 1510709198

so when you tack on the milliseconds

auto tse = now.time_since_epoch();
auto now_ms = duration_cast<milliseconds>(tse);
auto now_s = duration_cast<seconds>(tse);
auto jst_ms = now_ms - now_s;
DWORD msecs = jst_ms.count();
msecs = 875

secs should be 1510709197, but look at now_s, it's right

now_s {_MyRep=1510709197 }  

Upvotes: 0

bames53
bames53

Reputation: 88155

Using code from this answer:

#include <chrono>
#include <ctime>
#include <iostream>

template <typename Duration>
void print_time(tm t, Duration fraction) {
    using namespace std::chrono;
    std::printf("[%04u-%02u-%02u %02u:%02u:%02u.%03u]\n", t.tm_year + 1900,
                t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec,
                static_cast<unsigned>(fraction / milliseconds(1)));

    // VS2013's library has a bug which may require you to replace
    // "fraction / milliseconds(1)" with
    // "duration_cast<milliseconds>(fraction).count()"
}

int main() {
    using namespace std;
    using namespace std::chrono;

    system_clock::time_point now = system_clock::now();
    system_clock::duration tp = now.time_since_epoch();

    tp -= duration_cast<seconds>(tp);

    time_t tt = system_clock::to_time_t(now);

    print_time(*gmtime(&tt), tp);
    print_time(*localtime(&tt), tp);
}

One thing to keep in mind is that the fact that the timer returns values of sub-millisecond denominations does not necessarily indicate that the timer has sub-millisecond resolution. I think Windows' implementation in VS2015 may finally be fixed, but the timer they've been using to back their chrono implementation so far has been sensitive to the OS timeBeginPeriod() setting, displaying varying resolution, and the default setting is I think 16 milliseconds.

Also the above code assumes that neither UTC nor your local timezone are offset from the epoch of std::chrono::system_clock by a fractional second value.


Example of using Howard's date functions to avoid ctime: http://coliru.stacked-crooked.com/a/98db840b238d3ce7

Upvotes: 15

Alex
Alex

Reputation: 467

This answer still uses a bit of C API but is only used in the function, so you can forget about it:

template<typename T>
void print_time(std::chrono::time_point<T> time) {
    using namespace std;
    using namespace std::chrono;

    time_t curr_time = T::to_time_t(time);
    char sRep[100];
    strftime(sRep,sizeof(sRep),"%Y-%m-%d %H:%M:%S",localtime(&curr_time));

    typename T::duration since_epoch = time.time_since_epoch();
    seconds s = duration_cast<seconds>(since_epoch);
    since_epoch -= s;
    milliseconds milli = duration_cast<milliseconds>(since_epoch);

    cout << '[' << sRep << ":" << milli.count() << "]\n";
}

This is merely a rewrite of the code that bames53, but using strftime to shorten the code a bit.

Upvotes: 4

Jay Miller
Jay Miller

Reputation: 2234

std::chrono give you utilities to represent a point in time or the elapsed duration between two points in time. It allows you to get information about these time intervals.

It does not provide any calendar information. Unfortunately, at this time there are no tools in the C++ standard for these. boost::date_time may be helpful here.

Upvotes: 0

Related Questions