2017-10-19 2 views
1

Angenommen, ich empfange von einem Webserver eine Zeichenfolge zu analysieren. Diese Zeichenfolge enthält ein Datum im Format YYYY-MM-DD. Was ich will, ist, es in den Zeitstempel zu konvertieren, der den Beginn dieses Tages darstellt, daher möchte ich keine Sekunden, Minuten und Stunden.Parse Datum String zum Entfernen von Stunden, Minuten und Sekunden aus Timestamp

Als Dummy Beispiel, ich versuche, den Zeitstempel des aktuellen Tages zu extrahieren, einmal in das Format YYYY-MM-DD umgewandelt. Hier ist der Code:

#include <chrono>                                                                
#include <iomanip>                                                                
#include <iostream>                                                                
#include <sstream> 
int main() 
{ 
    // Current time at GMT 
    std::time_t now = std::time(0); 
    std::tm *now_tm = std::gmtime(&now); 
    std::ostringstream oss; 
    // Extract yyyy-mm-dd = %F 
    oss << std::put_time(now_tm, "%F"); 
    // Use oss to get a date without seconds from 
    // current time at gmt 
    std::tm tm; 
    std::istringstream ss(oss.str()); 
    ss >> std::get_time(&tm, "%F"); 
    std::time_t current_date = std::mktime(&tm); 
    std::cout << oss.str() << std::endl; 
    std::cout << "cd: " << current_date << std::endl; 
    return 0; 
} 

Die Ausgabe lautet:

2017-10-19 
cd: 1908337984324104 

Die extrahierte Zeitstempel eindeutig falsch ist. Wo ist das Problem bei der Analyse der 2017-10-19 Zeichenfolge mit dem %F Format?

Antwort

1

Die documentation of std::get_time listet keine Konvertierungsspezifikation% F auf. Beim Überprüfen des Stream-Flags (was Sie immer tun sollten!), Wird es auch sagen, dass die Konvertierung fehlgeschlagen ist, zumindest mit meinem Compiler.

Durch Ersetzen von% Y-% m-% d ist die Konvertierung erfolgreich. Schließlich haben Sie die tm-Variable standardmäßig erstellt, ohne sie auf Null zu setzen (z. B. durch Wertinitialisierung). Wenn dies auch zur Festsetzung der Code funktioniert wie erwartet:

#include <chrono>                                                                
#include <iomanip>                                                                
#include <iostream>                                                                
#include <sstream> 
int main() 
{ 
    // Current time at GMT 
    std::time_t now = std::time(0); 
    std::tm *now_tm = std::gmtime(&now); 
    std::ostringstream oss; 
    // Extract yyyy-mm-dd = %F 
    oss << std::put_time(now_tm, "%Y-%m-%d"); 
    // Use oss to get a date without seconds from 
    // current time at gmt 
    std::tm tm{ }; // value-initialize! 
    std::istringstream ss(oss.str()); 
    ss >> std::get_time(&tm, "%Y-%m-%d"); 
    if(!ss) std::cout << "conversion error\n"; 
    else { 
     std::time_t current_date = std::mktime(&tm); 
     std::cout << current_date << '\n'; 
     std::cout << "cd: " << current_date << '\n'; 
    } 
    return 0; 
} 

http://coliru.stacked-crooked.com/a/d86aa1e1d890a14d

+0

Vielen Dank! Ich schaute mir die Dokumentation einer anderen zeitbildenden Funktion an und vermutete, dass es genauso sein würde. Ich habe mich geirrt. – nessuno

1

Sie können dies tun, indem Sie Howard Hinnant's, free, open-source, header-only chrono-extension library die Sicherheit des chrono Typ-System, ohne zu verlassen.

#include "date/date.h" 
#include <iostream> 

int 
main() 
{ 
    std::istringstream ss{"2017-10-19"}; 
    date::sys_seconds tp; 
    ss >> date::parse("%F", tp); 
    std::cout << date::format("%F\n", tp); 
    using date::operator<<; 
    std::cout << "cd: " << tp.time_since_epoch() << '\n'; 
} 

date::sys_seconds ist ein std::chrono::time_point die chrono::seconds in Unix Time zählt. Mit %F können Sie direkt in das Programm einlesen. Sie können es auch formatieren, indem Sie die gleiche Formatzeichenfolge verwenden (%F) und außerdem die zugrunde liegende Anzahl von chrono::seconds untersuchen. Dieses Programm gibt aus:

2017-10-19 
cd: 1508371200s 
+0

Das ist großartig. Danke für Ihren Vorschlag. Behalte meine Erwiderung – nessuno

Verwandte Themen