XMLCoder icon indicating copy to clipboard operation
XMLCoder copied to clipboard

iso8601 formatter with RFC3339 is too restrictive

Open marcblanchet opened this issue 5 years ago • 2 comments

let formatter = ISO8601DateFormatter()
formatter.formatOptions = .withInternetDateTime

this formatOption restricts to RFC3339 format. That format requires timezone. Sometimes the timezone is not included, therefore results in error. I manage to create a custom formatter instantiating let formatter = ISO8601DateFormatter() formatter.formatOptions = [.withColonSeparatorInTime, .withDashSeparatorInDate, .withFullDate, .withTime] which supports strings without timezone, but for strings with timezone, the timezone is lost in the resulting date.

would be good that the parser will be more liberal in accepting date strings

marcblanchet avatar Sep 13 '19 16:09 marcblanchet

Hi @marcblanchet, we don't use any custom parsing of date strings within XMLCoder and you can always pass a your own DateFormatter instance. From that perspective, it's the responsibility of the user to pass a DateFormatter instance that's more liberal in accepting date strings.

Were you able to find options that work for you case? If not, what do you think the alternative API should be?

MaxDesiatov avatar Oct 05 '19 20:10 MaxDesiatov

taking xsd schemas, xsd defines multiple date formats, so even within a single XML, one may encounter different kinds of date and time formats. So it would be great to provide a more liberal way to support dates/times, at least the ones clearly defined. I would certainly see an option that says: try any. Yes, I wrote a custom one which tries in sequence multiple formats until it can't find anything. Here is an extract of what I wrote. Would be great to have something like that in the base

           let ourFormatOptions: [ISO8601DateFormatter.Options] = [
                [.withColonSeparatorInTime, .withDashSeparatorInDate, .withFullDate, .withTime],
                [.withFullDate],
                [.withTime],
                [.withYear],
                [.withDay],
            ]
            var iterator = ourFormatOptions.makeIterator()
            while let it = iterator.next() {
                df.formatOptions = it
                if let date = df.date(from: text) {
                    return date
                }
            }

marcblanchet avatar Oct 05 '19 20:10 marcblanchet