Подтвердить что ты не робот

Как создать дату и время 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?

4b9b3361

Ответ 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