I\'m working with the Azure REST API and they are using this to create the request body for table storage:
DateTime.UtcNow.ToString(\"o\")
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
OK so I've modified a few solutions that I've found as came up with the following :
static QString getTimeZoneOffset()
{
QDateTime dt1 = QDateTime::currentDateTime();
QDateTime dt2 = dt1.toUTC();
dt1.setTimeSpec(Qt::UTC);
int offset = dt2.secsTo(dt1) / 3600;
if (offset >= 0)
return QString("%1").arg(offset).rightJustified(2, '0',true).prepend("+");
return QString("%1").arg(offset).rightJustified(2, '0',true);
}
Then to easily format a date ( yyyy-MM-dd'T'HH:mm:ss.SSSZ ) :
static QString toISO8601ExtendedFormat(QDateTime date)
{
QString dateAsString = date.toString(Qt::ISODate);
QString timeOffset = Define::getTimeZoneOffset();
qDebug() << "dateAsString :" << dateAsString;
qDebug() << "timeOffset :" << timeOffset;
timeOffset = QString(".000%1%2").arg(timeOffset).arg("00");
qDebug() << "timeOffset replaced :" << timeOffset;
if(dateAsString.contains("Z",Qt::CaseInsensitive))
dateAsString = dateAsString.replace("Z",timeOffset);
else
dateAsString = dateAsString.append(timeOffset);
qDebug() << "dateAsString :" << dateAsString;
return dateAsString;
}
For example GMT +2 would look like this : 2013-10-14T00:00:00.000+0200
Did it like this:
using namespace boost::posix_time;
ptime t = microsec_clock::universal_time();
qDebug() << QString::fromStdString(to_iso_extended_string(t) + "0Z"); // need 7 digits
You can use this function which uses std::put_time
with a std::ostringstream
to generate the resulting std::string
.
#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>
/**
* Generate a UTC ISO8601-formatted timestamp
* and return as std::string
*/
std::string currentISO8601TimeUTC() {
auto now = std::chrono::system_clock::now();
auto itt = std::chrono::system_clock::to_time_t(now);
std::ostringstream ss;
ss << std::put_time(gmtime(&itt), "%FT%TZ");
return ss.str();
}
// Usage example
int main() {
std::cout << currentISO8601TimeUTC() << std::endl;
}
Reference: https://techoverflow.net/2018/03/30/iso8601-utc-time-as-stdstring-using-c11-chrono/
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";
}
Boost has a library for this.
I.e. posix_time has the from_iso_string()
and to_iso_string()
functions.