strptime () equivalente en Windows?

¿Hay una buena implementación equivalente de strptime() disponible para Windows? Lamentablemente, esta función POSIX no parece estar disponible.

Open Group description of strptime – summary: convierte una cadena de texto como "MM-DD-YYYY HH:MM:SS" en una tm struct , lo opuesto a strftime() .

Se puede encontrar una versión de código abierto (licencia BSD) de strptime() aquí: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/time/strptime.c?rev=HEAD

Deberá agregar la siguiente statement para usarla:

 char *strptime(const char * __restrict, const char * __restrict, struct tm * __restrict); 

Si no desea portar ningún código o condenar su proyecto para boost, puede hacer esto:

  1. analizar la fecha usando sscanf
  2. luego copie los enteros en una struct tm (reste 1 del mes y 1900 del año – los meses son 0-11 y los años comienzan en 1900)
  3. finalmente, use mktime para obtener un entero de época UTC

Solo recuerde establecer el miembro isdst de struct tm en -1, de lo contrario tendrá problemas de ahorro de luz diurna.

Esto hace el trabajo:

 #include "stdafx.h" #include "boost/date_time/posix_time/posix_time.hpp" using namespace boost::posix_time; int _tmain(int argc, _TCHAR* argv[]) { std::string ts("2002-01-20 23:59:59.000"); ptime t(time_from_string(ts)); tm pt_tm = to_tm( t ); 

Observe, sin embargo, que la cadena de entrada es AAAA-MM-DD

Suponiendo que está usando Visual Studio 2015 o superior, puede usar esto como un reemplazo directo para strptime:

 #include  #include  #include  extern "C" char* strptime(const char* s, const char* f, struct tm* tm) { // Isn't the C++ standard lib nice? std::get_time is defined such that its // format parameters are the exact same as strptime. Of course, we have to // create a string stream first, and imbue it with the current C locale, and // we also have to make sure we return the right things if it fails, or // if it succeeds, but this is still far simpler an implementation than any // of the versions in any of the C standard libraries. std::istringstream input(s); input.imbue(std::locale(setlocale(LC_ALL, nullptr))); input >> std::get_time(tm, f); if (input.fail()) { return nullptr; } return (char*)(s + input.tellg()); } 

Solo tenga en cuenta que para las aplicaciones multiplataforma, std::get_time no se implementó hasta GCC 5.1, por lo que cambiar a la llamada a std::get_time directamente puede no ser una opción.

Una alternativa es usar GetSystemTime y enviar la información de tiempo a una función que lo analiza de acuerdo con su formato usando vsnprintf_s . En el siguiente ejemplo, hay una función que crea una cadena de tiempo con mili de precisión. A continuación, envía la cadena a una función que lo formatea de acuerdo con el formato deseado:

 #include  #include  #include  #include  std::string FormatToISO8601 (const std::string FmtS, ...) { CStringA BufferString; try { va_list VaList; va_start (VaList, FmtS); BufferString.FormatV (FmtS.c_str(), VaList); } catch (...) {} return std::string (BufferString); } void CreateISO8601String () { SYSTEMTIME st; GetSystemTime(&st); std::string MyISO8601String = FormatToISO8601 ("%4u-%02u-%02uT%02u:%02u:%02u.%03u", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); }