Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I construct an ISO 8601 datetime in C++?

Tags:

c++

qt

azure

People also ask

How do I format a date in ISO 8601?

ISO 8601 represents date and time by starting with the year, followed by the month, the day, the hour, the minutes, seconds and milliseconds. For example, 2020-07-10 15:00:00.000, represents the 10th of July 2020 at 3 p.m. (in local time as there is no time zone offset specified—more on that below).

Is ISO 8601 same as UTC?

They're for different purposes. UTC is the primary time standard by which the world regulates clocks and time. ISO is standard format time.

What time zone is ISO 8601?

Time zones in ISO 8601 are represented as local time (with the location unspecified), as UTC, or as an offset from UTC.

How do I convert date and time to ISO?

The date. toISOString() method is used to convert the given date object's contents into a string in ISO format (ISO 8601) i.e, in the form of (YYYY-MM-DDTHH:mm:ss. sssZ or ±YYYYYY-MM-DDTHH:mm:ss. sssZ).


If the time to the nearest second is precise enough, you can use strftime:

#include <ctime>
#include <iostream>

int main() {
    time_t now;
    time(&now);
    char buf[sizeof "2011-10-08T07:07:09Z"];
    strftime(buf, sizeof buf, "%FT%TZ", gmtime(&now));
    // this will work too, if your compiler doesn't support %F or %T:
    //strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
    std::cout << buf << "\n";
}

If you need more precision, you can use Boost:

#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>

int main() {
    using namespace boost::posix_time;
    ptime t = microsec_clock::universal_time();
    std::cout << to_iso_extended_string(t) << "Z\n";
}

Using the date library (C++11):

template <class Precision>
string getISOCurrentTimestamp()
{
    auto now = chrono::system_clock::now();
    return date::format("%FT%TZ", date::floor<Precision>(now));
}

Example usage:

cout << getISOCurrentTimestamp<chrono::seconds>();
cout << getISOCurrentTimestamp<chrono::milliseconds>();
cout << getISOCurrentTimestamp<chrono::microseconds>();

Output:

2017-04-28T15:07:37Z
2017-04-28T15:07:37.035Z
2017-04-28T15:07:37.035332Z

I should point out I am a C++ newb.

I needed string with a UTC ISO 8601 formatted date and time that included milliseconds. I did not have access to boost.

This is more of a hack than a solution, but it worked well enough for me.

std::string getTime()
{
    timeval curTime;
    gettimeofday(&curTime, NULL);

    int milli = curTime.tv_usec / 1000;
    char buf[sizeof "2011-10-08T07:07:09.000Z"];
    char *p = buf + strftime(buf, sizeof buf, "%FT%T", gmtime(&curTime.tv_sec));
    sprintf(p, ".%dZ", milli);

    return buf;
}

The output looks like: 2016-04-13T06:53:15.485Z


Boost has a library for this.

I.e. posix_time has the from_iso_string() and to_iso_string() functions.


With C++20, time point formatting (to string) is available in the (chrono) standard library. https://en.cppreference.com/w/cpp/chrono/system_clock/formatter

#include <chrono>
#include <format>
#include <iostream>

int main()
{
   const auto now = std::chrono::system_clock::now();
   std::cout << std::format("{:%FT%TZ}", now) << '\n';
}

Output

2021-11-02T15:12:46.0173346Z

It works in Visual Studio 2019 with the latest C++ language version (/std:c++latest).