Parsing ISO 8601 date with optional fractional second using ICU

I used the format string yyyy-MM-dd'T'HH:mm:ss.SSSXXXwith icu :: SimpleDateFormat .

Although it works for date and time strings with fractional digits. Examples:

2016-03-31T15: 04: 32.049Z

2016-03-31T15: 04: 32.05Z

2016-03-31T15: 04: 32.3Z

It does not parse strings without a fractional second (for example 2016-03-31T15:08:51Z), returning the error code U_ILLEGAL_ARGUMENT_ERROR.

I tried some other format combinations to no avail: some failed with an error code, others ignored milliseconds.

Does ICU support optional fractional second parsing?

+4
source share
1 answer

ICU , .

- . () datetime :

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

All Articles