10

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)  
Ketan Parmar
  • 27,092
  • 9
  • 50
  • 75
user49hc
  • 121
  • 7
  • please add some code snippets with examples of your problem and the solution that you may have tried. – Nishant Sep 15 '15 at 21:11
  • What are the other possible values of date format that you want to handle in your code? – Nishant Sep 15 '15 at 21:20
  • I don't know all the possible variations, but it could be things like 'January 3, 1966' or 'Jan 3, 1966' or '3 Jan 1966'. – user49hc Sep 15 '15 at 22:15

2 Answers2

29

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
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
1

Tested in swift 4, xcode 9

extension String {
        var detectDate: Date? {
            let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.date.rawValue)
            let matches = detector?.matches(in: self, options: [], range: NSMakeRange(0, self.utf16.count))
            return matches?.first?.date
        }
    }

Test:

print("2018-11-04T23:59:00+00:00".detectDate ?? "") // 2018-11-04 10:00:00 +0000

print("2018/11/4".detectDate ?? "") // 2018-11-04 10:00:00 +0000

Bassant Ashraf
  • 1,531
  • 2
  • 16
  • 23
  • This caused a bug for example, 4/8/2020 sometimes converted to 4 August and another time was converted to 8 Apr , as it's unknown whicj is month and which is the day – Bassant Ashraf Dec 08 '19 at 13:34