Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Outputting date in ISO 8601 format

Tags:

c++

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"

like image 740
user308827 Avatar asked Apr 29 '16 00:04

user308827


3 Answers

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
like image 136
Baum mit Augen Avatar answered Oct 11 '22 22:10

Baum mit Augen


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.

like image 33
Uri Avatar answered Oct 11 '22 23:10

Uri


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");
like image 35
Matt Avatar answered Oct 11 '22 21:10

Matt