strptime()-Äquivalent unter Windows?

Lesezeit: 5 Minuten

strptime Aquivalent unter Windows
An̲̳̳ zeichnete

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

Öffnen Sie die Gruppenbeschreibung von strptime – Zusammenfassung: Es konvertiert eine Textzeichenfolge wie z "MM-DD-YYYY HH:MM:SS" in ein tm structdas Gegenteil von strftime().

  • Es würde helfen, wenn Sie eine Beschreibung von strptime hinzufügen, damit ich es nicht googeln muss 🙂

    – JaredPar

    26. November 2008 um 19:21 Uhr

strptime Aquivalent unter Windows
amwinter

Wenn Sie keinen Code portieren oder Ihr Projekt zum Boosten verurteilen möchten, können Sie dies tun:

  1. Analysieren Sie das Datum mit sscanf
  2. Kopieren Sie dann die ganzen Zahlen in a struct tm (subtrahieren Sie 1 vom Monat und 1900 vom Jahr – Monate sind 0-11 und Jahre beginnen im Jahr 1900)
  3. endlich nutzen mktime um eine UTC-Epochen-Ganzzahl zu erhalten

Denken Sie daran, die einzustellen isdst Mitglied von struct tm auf -1, sonst haben Sie Probleme mit der Sommerzeit.

  • Beachten Sie, dass mktime funktioniert mit Daten im Bereich von 1970 bis 2038, aber Sie können verwenden _mktime64 was mit Daten im Bereich 1970 ~ 3000 funktioniert 🙂

    – Liho

    7. Dezember 2012 um 17:15 Uhr

  • Manchmal ist es sinnvoll zu füllen isdst Mit seinem aktuellen Wert können Sie es mit bekommen localtime(&current_time)->tm_isdst;wo current_time ist die aktuelle Zeit in time_t Format, wie zurückgegeben von time(&current_time).

    – Benutzer

    19. Oktober 2014 um 8:46 Uhr

  • @amwinter wie wäre es mit tm_wday und tm_yday ?

    – aderchox

    11. Dezember 2019 um 16:58 Uhr

  • @aderchox verwenden Sie einfach mktime(), um die Zeit zu normalisieren, und Sie erhalten einen korrekten tm_wday und tm_yday.

    – Sam

    26. September 2020 um 9:57 Uhr

  • Zu 2. Nicht erforderlich, wenn direkt in &t.tm_day gescannt wird. Denken Sie daran, die Struktur auf Null zu setzen, z. B.: struct tm my_time{0};

    – vSzemkel

    29. September 2020 um 8:12 Uhr

1646887207 957 strptime Aquivalent unter Windows
Orvid König

Angenommen, Sie verwenden Visual Studio 2015 oder höher, können Sie dies 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());
}

Beachten Sie nur, dass für plattformübergreifende Anwendungen std::get_time wurde erst mit GCC 5.1 implementiert, also Umstellung auf Calling std::get_time direkt ist vielleicht keine Option.

  • Danke, dass Sie kopieren und einfügen können.

    – chtenb

    23. November 2016 um 16:18 Uhr

  • aber std::get_time ist hier auf VS2015 kaputt

    – schneidig

    13. Dezember 2016 um 21:58 Uhr

  • 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.

    – Orvid König

    31. Dezember 2016 um 1:57 Uhr

  • +1, aber damit es funktioniert, musste ich die folgende Zeile nach hinzufügen get_time() Linie: if(input.eof()) return (char *)(s + strlen(s));

    – jez

    23. Mai 2021 um 21:49 Uhr

  • Es gibt einen Unterschied im Verhalten zwischen diesen beiden (GCC11 und glibc und STL Ende 2021): Diese C++-Versionen werden abgelehnt strptime("2018-11-41", "%Y-%m-%d", x)Rückkehr a nullptrwährend die C-Version erfolgreich ist und das Trailing hinterlässt "1" ungeparst.

    – Jan Kundrat

    10. Dezember 2021 um 19:36 Uhr

Eine Open-Source-Version (BSD-Lizenz) von strptime() finden Sie hier: http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/time/strptime.c?rev=HEAD

Sie müssen die folgende Deklaration hinzufügen, um sie zu verwenden:

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

  • Visual Studio 2008 beschwert sich über „fatal error C1083: Cannot open include file: ‚sys/cdefs.h‘: No such file or directory“

    – Ozair Kafray

    1. November 2018 um 10:44 Uhr

  • Wie ist das die akzeptierte Antwort? Es verwendet eine Reihe von Headern, die nicht in Windows enthalten sind.

    Benutzer2329125

    9. September 2019 um 14:28 Uhr

  • Diese Lösung funktioniert nicht unter Windows (und unter Linux oder macOS wird sie nicht benötigt!)

    – Headbanger

    11. Dezember 2019 um 12:28 Uhr

Das macht die Arbeit:

#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 YYYY-MM-DD ist

Eine Alternative ist die Verwendung GetSystemTime und senden Sie die Zeitinformationen an eine Funktion, die sie gemäß Ihrem Format analysiert vsnprintf_s. Im Beispiel unten gibt es eine Funktion, die eine Zeitzeichenfolge mit Millisekunden-Präzision erstellt. Anschließend sendet es die Zeichenfolge an eine Funktion, die sie gemäß 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);
}

  • Sie haben die Dinge rückwärts. Die Frage fragt nach einer Möglichkeit, a umzuwandeln Zeichenfolgendarstellung in ein struct tmwährend Sie eine (schlechte) Implementierung von präsentiert haben strftime.

    – Inspektionsfähig

    16. Juni 2015 um 14:36 ​​Uhr

  • Sie haben die Dinge rückwärts. Die Frage fragt nach einer Möglichkeit, a umzuwandeln Zeichenfolgendarstellung in ein struct tmwährend Sie eine (schlechte) Implementierung von präsentiert haben strftime.

    – Inspektionsfähig

    16. Juni 2015 um 14:36 ​​Uhr

986210cookie-checkstrptime()-Äquivalent unter Windows?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy