9

How can I get a date in the following format in C++:

2016-04-26T19:50:48Z

#include <chrono>
#include <ctime>

time_t _tm = time(NULL);
struct tm*curtime = localtime(&_tm);

And outputting as asctime(curtime)

The current output is: "Thu Apr 28 16:02:41 2016\n"

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
user308827
  • 21,227
  • 87
  • 254
  • 417

3 Answers3

14

Documentation is your friend:

std::time_t t
    = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
std::cout << std::put_time( std::localtime( &t ), "%FT%T%z" );

in my system yields

2016-04-29T02:48:56+0200
Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Do you know how to display the millisecond part of the timestamp? – aviggiano Aug 03 '17 at 22:50
  • @aviggiano I don't think the millisecond part is part of the ISO 8601 format, so that would be a new question. – Baum mit Augen Oct 17 '17 at 09:31
  • 1
    I have to disagree (see https://en.wikipedia.org/wiki/ISO_8601#Times and especially the last paragraph there). Basically, you can put a decimal fraction part behind any of the time components, but it must be the last given. For millisecond precision it would be something like `2019-06-18T18:12:34.456` (or comma instead of decimal point), but the `put_time()` method doesn't seem to support a format specifier for the millisecond part. One solution that helped me, was this one: https://stackoverflow.com/a/35157784/5823275. – Chris Tophski Jun 18 '19 at 17:42
4

Based on @Uri's answer which fixes a few bugs and shows the time in the proper timezone along with the milliseconds in ISO8601 format:

auto now = std::chrono::system_clock::now();
std::time_t time = std::chrono::system_clock::to_time_t(now);
std::tm* now_tm = std::localtime(&time);
long long timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();

std::cout << std::setfill('0') 
          << std::put_time(now_tm, "%FT%H:%M:")
          << std::setw(2) << (timestamp / 1000) % 60 << '.'
          << std::setw(3) << timestamp % 1000
          << std::put_time(now_tm, "%z");
Matt
  • 322
  • 6
  • 12
2

I'm combining the std::localtime which gives me calendar values, with std::chrono functions that gives me the precise methods. Here is my code:

#include <ctime>
#include <chrono>

...

auto now = std::chrono::system_clock::now();
auto now_c = std::chrono::system_clock::to_time_t(now)
auto now_tm = std::localtime(&now_c);
auto now_since_epoch = now.time_since_epoch();    // since 1970
auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now_since_epoch).count();

std::cout << std::setfill('0') <<
    std::setw(4) << now_tm->tm_year + 1900 << '-' <<
    std::setw(2) << now_tm->tm_mon + 1 << '-' <<
    std::setw(2) << now_tm->tm_mday << 'T' <<
    std::setw(2) << now_ms % (24*60*60*1000) << ':' <<
    std::setw(2) << now_ms % (60*60*1000) << ':' <<
    std::setw(2) << now_ms % (60*1000) << '.' <<
    std::setw(3) << now_ms % (1000);

Although verbose, it is actually doing less than strftime.

Uri London
  • 10,631
  • 5
  • 51
  • 81