Как создать дату и время ISO 8601 на С++?
Я работаю с API-интерфейсом REST Azure, и они используют это для создания тела запроса для хранения таблиц:
DateTime.UtcNow.ToString("o")
Который производит:
2012-03-02T04: 07: 34.0218628Z
Он называется "туда-обратно" и, очевидно, является стандартом ISO (см. Http://en.wikipedia.org/wiki/ISO_8601), но я не знаю, как его повторить после прочтения статьи в вики.
Кто-нибудь знает, есть ли в Boost поддержка для этого или, возможно, Qt?
Ответы
Ответ 1
Если время до ближайшей секунды достаточно точный, вы можете использовать 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";
}
Если вам нужна более высокая точность, вы можете использовать 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";
}
Ответ 2
Используя библиотеку date (С++ 11):
template <class Precision>
string getISOCurrentTimestamp()
{
auto now = chrono::system_clock::now();
return date::format("%FT%TZ", date::floor<Precision>(now));
}
Пример использования:
cout << getISOCurrentTimestamp<chrono::seconds>();
cout << getISOCurrentTimestamp<chrono::milliseconds>();
cout << getISOCurrentTimestamp<chrono::microseconds>();
Вывод:
2017-04-28T15:07:37Z
2017-04-28T15:07:37.035Z
2017-04-28T15:07:37.035332Z
Ответ 3
Я должен указать, что я новичок C++.
Мне нужна была строка с датой и временем в формате UTC ISO 8601, включающая миллисекунды. У меня не было доступа к надстройке.
Это скорее взлом, чем решение, но для меня это сработало достаточно.
std::string getTime()
{
timeval curTime;
time_t now;
time(&now);
gettimeofday(&curTime, NULL);
int milli = curTime.tv_usec / 1000;
char buf[sizeof "2011-10-08T07:07:09.000Z"];
strftime(buf, sizeof buf, "%FT%T", gmtime(&now));
sprintf(buf, "%s.%dZ", buf, milli);
return buf;
}
Вывод выглядит так: 2016-04-13T06: 53: 15.485Z
Ответ 4
У Boost есть библиотека для этого.
Т.е. posix_time имеет функции from_iso_string()
и to_iso_string()
.
Ответ 5
В Qt это будет:
QDateTime dt = QDateTime::currentDateTime();
dt.setTimeSpec(Qt::UTC); // or Qt::OffsetFromUTC for offset from UTC
qDebug() << QDateTime::currentDateTime().toString(Qt::ISODate);
Ответ 6
ОК, поэтому я изменил несколько решений, которые я нашел, когда придумал следующее:
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);
}
Затем, чтобы легко форматировать дату (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;
}
Например GMT +2 будет выглядеть так:
2013-10-14T00: 00: 00,000 + 0200
Ответ 7
Было ли это так:
using namespace boost::posix_time;
ptime t = microsec_clock::universal_time();
qDebug() << QString::fromStdString(to_iso_extended_string(t) + "0Z"); // need 7 digits