time_t library functions c++ c windows datetime

c++ - library - strptime() equivalente en Windows?



time functions in c (5)

¿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() .


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


Se puede encontrar una versión de código abierto (licencia BSD) de strptime() aquí:

Deberá agregar la siguiente declaración 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 aumentar, 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.


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

#include <time.h> #include <iomanip> #include <sstream> 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 <string> #include <cstdio> #include <cstdarg> #include <atlstr.h> 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); }