CoreOffice / XMLCoder

Easy XML parsing using Codable protocols in Swift
https://coreoffice.github.io/XMLCoder/
MIT License
787 stars 105 forks source link

iso8601 formatter with RFC3339 is too restrictive #131

Open marcblanchet opened 4 years ago

marcblanchet commented 4 years ago
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

MaxDesiatov commented 4 years ago

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?

marcblanchet commented 4 years ago

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
                }
            }