简体   繁体   中英

How to handle multiple date formats?

When I get to the df.date() line below, the app crashes when a date with this format 2016-12-27 14:40:46 +0000 is used:

fatal error: unexpectedly found nil while unwrapping an Optional value

And I also see this:

error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

I have strings that can be in this format

12/27/2016

but sometimes in this format

2016-12-27 14:40:46 +0000      

Here is the code snippet that crashes on the above format:

let mydate = "12/27/2016" //this works but not the longer format
let df = DateFormatter()
df.dateFormat = "MM/dd/yyyy" //this is the format I want both dates to be in
newDate:Date = df.date(from: mydate)

How do I handle both formats using basically one function?

Check if the date string contains a slash and set the date format accordingly:

if mydate.contains("/") {
    df.dateFormat = "MM/dd/yyyy"
}  else {
    df.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
}

You can try an approach that is very clean in your code. You can add this extension:

extension DateFormatter {

    func dateFromMultipleFormats(fromString dateString: String) -> Date? {
        var formats: [String] = [
        "yyyy-MM-dd hh:mm:ss.SSSSxx",
        "yyyy-MM-dd hh:mm:ss.SSSxxx",
        "yyyy-MM-dd hh:mm:ss.SSxxxx",
        "yyyy-MM-dd hh:mm:ss.Sxxxxx",
        "yyyy-MM-dd hh:mm:ss"
        ]
    for format in formats {
        self.dateFormat = format
        if let date = self.date(from: dateString) {
                return date
            }
        }
        return nil
    }
}

then just try changing the formats array in the function to whatever formats you may need. Now just use your formatter like this:

if let myDate = dateFormatter.dateFromMultipleFormats(fromString: mydate) {
    print("success!")
} else {
    print("add another format for \(mydate)")
}

I think the best way to do this is using two DateFormatters , one for iso8601 format and other for this short format.

(My code below uses an extension of DateFormatter, but you can use a method / helper / anything else with these two formatters) .

Swift 3

extension DateFormatter {
    static let iso8601DateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar.current // Set the Calendar
        formatter.timeZone = TimeZone(secondsFromGMT: 0) // Set the timezone
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"
        return formatter
    }()

    static let shortDateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.calendar = Calendar.current // Set the Calendar
        formatter.timeZone = TimeZone(secondsFromGMT: 0) // Set the timezone
        formatter.dateFormat = "MM/dd/yyyy"
        return formatter
    }()

    static func date(string: String) -> Date? {
        if let iso8601Date = iso8601DateFormatter.date(from: string) {
            return iso8601Date
        } else if let shortDate = shortDateFormatter.date(from: string) {
            return shortDate
        } else {
            return nil
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM