2016-03-31 14 views
4

Ich verwendete yyyy-MM-dd'T'HH:mm:ss.SSSXXX Formatzeichenfolge mit icu :: SimpleDateFormat.Parse ein ISO 8601 Datum-Uhrzeit mit optionalen Sekundenbruchteil mit ICU

Obwohl es für Datum-Uhrzeit-Zeichenfolgen mit Nachkommastellen funktioniert. Beispiele:

2016-03-31T15: 04: 32.049Z

2016-03-31T15: 04: 32.05Z

2016-03-31T15: 04: 32.3Z

Es analysiert keine Strings ohne Bruchteile von Sekunden (z. B. 2016-03-31T15:08:51Z) und gibt einen Fehlercode U_ILLEGAL_ARGUMENT_ERROR zurück.

Ich habe versucht, einige andere Formatkombinationen vergebens: einige fehlschlagen mit einem Fehlercode, andere ignorieren Millisekunden.

Unterstützt die ICU sogar das Parsen einer optionalen Sekundenbruchteile?

+0

Dieses [freie Open-Source, header-only C++ 11/14/17-Bibliothek] (https: //howardhinnant.github .io/date/date.html) wird dies mit dem Syntaxstring '"% FT% TZ "' tun. Parsen Sie einfach in einen 'std :: chrono :: system_clock :: time_point'. –

+0

Ich erwarte, dass die endgültige Lösung mit mehreren Parsern zu parsen versuchen wird ... zuerst mit einem, der Sekunden spezifiziert, und dann ohne. Allerdings habe ich den U_ILLEGAL_ARGUMENT_ERROR bekommen, als ich das auch versucht habe, also bin ich mir auch nicht sicher, was ich falsch mache. Ich erwarte, dass die Probleme ähnlich sind, also gebe ich ein Kopfgeld darauf. Die von mir verwendeten Formate stammen von https://www.w3.org/TR/NOTE-datetime – markt1964

Antwort

1

Durch die ICU documentation gehen, habe ich keine Möglichkeit gefunden, optionale Teil in Musterspezifikation einzugeben.

Dieses Problem kann jedoch auf Anwendungsebene auf viele verschiedene Arten gelöst werden. Eine solcher Weise (vereinfacht) wird mehrere DATETIME Parsern wie folgt verwendet wird:

#include <iostream> 
#include <vector> 
#include "unicode/datefmt.h" 
#include "unicode/smpdtfmt.h" 

int main() { 

    UErrorCode err(U_ZERO_ERROR); 

    UnicodeString patternWithMilliseconds("yyyy-MM-dd'T'hh:mm:ss.SSSXXX"); 
    UnicodeString patternPlane("yyyy-MM-dd'T'hh:mm:ssX"); 

    // init ICU parsers 
    std::vector<SimpleDateFormat*> parsers = { 
      new SimpleDateFormat(patternWithMilliseconds, err), 
      new SimpleDateFormat(patternPlane, err) 
    }; 

    // get dates to convert 
    std::vector<UnicodeString> dates = { 
      UnicodeString("2016-03-31T15:04:32.049Z"), 
      UnicodeString("2017-10-30T15:05:33Z"), 
    }; 

    SimpleDateFormat resultFormatter(patternWithMilliseconds, err); 

    for(const auto& date : dates) { 

     UDate parsedDate; 
     UnicodeString result; 
     std::string resultConverted; 

     for(const auto& parser : parsers) { 
      err = U_ZERO_ERROR; 
      parsedDate = parser->parse(date, err); 
      if (err <= 0) break; 
     } 

     resultFormatter.format(parsedDate, result); 
     result.toUTF8String(resultConverted); 

     std::cout << resultConverted << std::endl; 
    } 

    for(auto& parser : parsers) { 
     delete parser; 
    } 

    return 0; 
}