Search code examples
iosswiftnsdatensdateformatter

Convert string with unknown format (any format) to date


I have data that contains a date string.

Normally it would be in a 'Jan. 3, 1966' type format, but because of international differences, it may not always be exactly that.

I need to read the data in and convert it into a standard date string ('YYYY-MM-DD').

Basically this is what I have so far:

var dataString = 'Jan. 3, 1966'  
var dateFormatter = NSDateFormatter()  
dateFormatter.dateFormat = # I DON'T KNOW THE EXACT INPUT FORMAT !
let dateValue = dateFormatter.dateFromString(dataString)  

Solution

  • Xcode 11.4 • Swift 5.2 or later

    You can use NSDataDetector as follow:

    extension String {
        var nsString: NSString { self as NSString }
        var length: Int { nsString.length }
        var nsRange: NSRange { .init(location: 0, length: length) }
        var detectDates: [Date]? {
            try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)
                    .matches(in: self, range: nsRange)
                .compactMap(\.date)
        }
    }
    

    extension Collection where Iterator.Element == String {
        var dates: [Date] { compactMap(\.detectDates).flatMap{$0}
        }
    }
    

    Testing:

    let dateStrings = ["January 3, 1966","Jan 3, 1966", "3 Jan 1966"]
    for dateString in dateStrings {
        if let dateDetected = dateString.detectDates?.first {
            print(dateDetected)
            // 1966-01-03 14:00:00 +0000
            // 1966-01-03 14:00:00 +0000
            // 1966-01-03 14:00:00 +0000
        }
    }
    
    
    let dateStrings = ["January 3, 1966","Jan 3, 1966", "3 Jan 1966"]
    
    for date in dateStrings.dates {
        print(date)
        // 1966-01-03 14:00:00 +0000
        // 1966-01-03 14:00:00 +0000
        // 1966-01-03 14:00:00 +0000
    }