2012-03-02 20 views
27

estoy trabajando con la API REST Azure y que están usando esto para crear el cuerpo de la petición de almacenamiento de tablas:¿Cómo construyo un datetime ISO 8601 en C++?

DateTime.UtcNow.ToString("o") 

que produce:

2012-03-02T04: 07: 34.0218628 Z

se llama "ida y vuelta", y al parecer es un estándar ISO (ver http://en.wikipedia.org/wiki/ISO_8601) pero no tengo ni idea de cómo replicar después de leer el artículo de wiki.

¿Alguien sabe si Boost tiene soporte para esto, o posiblemente Qt?

Nota: Me pondré en contacto con usted después del fin de semana después de compararlo con C#.

Respuesta

51

Si el tiempo al segundo más cercano es lo suficientemente precisa, puede utilizar 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"; 
} 

Si necesita más precisión, se puede usar 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"; 
} 
+8

You Want "% FT% TZ" (ISO 8601 usa la "T" para separar la fecha de la vez. –

3

En Qt, que sería:

QDateTime dt = QDateTime::currentDateTime(); 
dt.setTimeSpec(Qt::UTC); // or Qt::OffsetFromUTC for offset from UTC 
qDebug() << QDateTime::currentDateTime().toString(Qt::ISODate); 
+0

Los números al final son el problema, no la forma at de la cadena – chikuba

+0

Se refiere a la parte fraccionaria de los segundos (es decir .0218628)? Son opcionales ... – Koying

+0

¿cómo? no se pudo ver nada en el documento – chikuba

0

hice así:

using namespace boost::posix_time; 
ptime t = microsec_clock::universal_time(); 
qDebug() << QString::fromStdString(to_iso_extended_string(t) + "0Z"); // need 7 digits 
1

Aceptar lo he modificado algunas soluciones que he encontrado como ocurrió la siguiente :

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); 
} 

Entonces formato fácilmente a una fecha (aaaa-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; 
} 

Por ejemplo GMT +2 se vería así: 2013-10-14T00: 00: 00,000 + 0200

2

Debo señalar que soy un Novato C++.

Necesitaba una cadena con una fecha y hora UTC ISO 8601 formateada que incluyera milisegundos. No tuve acceso para impulsar.

Esto es más un truco que una solución, pero funcionó lo suficientemente bien para mí.

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"]; 
    strftime(buf, sizeof buf, "%FT%T", gmtime(&now)); 
    sprintf(buf, "%s.%dZ", buf, milli); 

    return buf; 
} 

La salida será similar a: 2016-04-13T06: 53: 15.485Z

9

Uso de la date biblioteca (C++ 11):

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

Ejemplo de uso:

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

de salida:

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