2008-11-26 16 views
32

Gibt es eine für Windows geeignete Implementierung von strptime()? Leider scheint diese POSIX-Funktion nicht verfügbar zu sein.strptime() entspricht Windows?

Open Group description of strptime - Zusammenfassung: Er wandelt eine Textzeichenfolge wie "MM-DD-YYYY HH:MM:SS" in eine tm struct, das Gegenteil von dem strftime().

+1

Es würde helfen, wenn Sie eine Beschreibung von strptime hinzugefügt haben, so muss ich nicht googeln :) – JaredPar

Antwort

14

Dies macht den Job :

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

Beachten Sie jedoch, dass die Eingabezeichenfolge ist YYYY-MM-DD

+2

+1 für den Hinweis auf eine Cross-Plattform-Lösung. – stinky472

28

Wenn Sie irgendeinen Code zu portieren oder verdammen Ihr Projekt wollen nicht zu steigern, können Sie dies tun:

  1. das Datum parsen mit sscanf
  2. kopieren Sie dann die ganzen Zahlen in ein struct tm (1 wird abgezogen Monat und 1900 von Jahr - Monate sind 0-11 und Jahren beginnen im Jahr 1900)
  3. schließlich mktime verwenden, um eine UTC Epoche integer zu erhalten

Denken Sie daran, das isdst Mitglied o einstellen f struct tm bis -1, sonst haben Sie Sommerzeit Probleme.

+3

Beachten Sie, dass 'mktime' mit Daten im Bereich von 1970 ~ 2038 arbeitet, aber Sie können [' _mktime64'] (http://msdn.microsoft.com/en-us/library/d1y53h2a%28v=vs.80) verwenden % 29.aspx), die mit Daten im Bereich 1970 ~ 3000 funktioniert :) – LihO

+1

Manchmal ist es sinnvoll, 'isdst' mit seinem aktuellen Wert zu füllen, Sie können es mit' localtime (& current_time) -> tm_isdst; ', wo' current_time 'ist die aktuelle Zeit im' time_t' Format, wie sie von 'time (& current_time)' zurückgegeben wird. – user

-3

Eine Alternative besteht darin, GetSystemTime zu verwenden und die Zeitinformation an eine Funktion zu senden, die es entsprechend Ihrem Format unter Verwendung vsnprintf_s analysiert. In dem unten gezeigten Beispiel gibt es eine Funktion, die eine Zeitzeichenfolge mit Millisekunde Genauigkeit erstellt. Er sendet dann die Zeichenfolge an eine Funktion, die es nach dem gewünschten Format formatiert:

#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); 
} 
+0

Sie haben Dinge rückwärts. Die Frage ist, nach einer Möglichkeit zu fragen, eine ** String-Repräsentation ** in eine 'struct tm' zu konvertieren, während Sie eine (schlechte) Implementierung von [strftime] (https://msdn.microsoft.com/en-us) präsentiert haben /library/fe06s4ak.aspx). – IInspectable

11

Sie Angenommen, Visual Studio 2015 oder höher verwenden, können Sie diese als Drop-in-Ersatz für strptime verwenden:

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

Bitte beachten Sie, dass bei plattformübergreifenden Anwendungen std::get_time erst mit GCC 5.1 implementiert wurde. Daher ist es möglicherweise keine Option, direkt auf std::get_time zuzugreifen.

+0

Danke für die Kopie-Pastable. –

+1

, aber std :: get_time ist auf VS2015 [hier] unterbrochen (http://stackoverflow.com/questions/35041344/trying-to-use-stdget-time-to-parse-yymmdd-and-failing#comment69466398_35041344) – dashesy

+0

Es ist nicht kaputt; Was sie zu tun versuchten, funktioniert auch nicht mit GCC oder Clang, und obwohl ich es nicht speziell getestet habe, funktioniert es wahrscheinlich auch nicht mit Strptime. –