user121095
user121095

Reputation: 813

Checking if date is matching date format

So it is pretty straight forward code. I have an input date that I want to validate against a specific format (the input date should perfectly match the date format specified), so I used the following code, input an invalid date (that should failed matching) but to my surprise it matches the date format and returns a valid date

import Foundation

let inputValue = "12/10/199" // Returns valid date even for "12/10.199"

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"


if let dateOfBirth = dateFormatter.date(from: inputValue) {
    print("Valid date \(dateOfBirth)") // Prints Valid date. Why?
}
else {
    print("Invalid date")
}

Console output

Valid date 0199-10-11 18:06:32 +0000

Upvotes: 0

Views: 856

Answers (2)

vadian
vadian

Reputation: 285082

According to Unicode Date Format Patterns only the two digit year format yy checks also for the length, 3 y and more add leading zeros up to the number of y.

My suggestion is to validate the string format with Regular Expression (the whole string must be 2 digits followed by a slash followed by two digits followed by a slash followed by 4 digits) and to use the new DateParseStrategy API introduced in iOS 15 / macOS 12 which is more comprehensible than the abstract string date format pattern.

let inputValue = "12/10/199"
let strategy = Date.ParseStrategy(format: "\(day: .twoDigits)/\(month: .twoDigits)/\(year: .defaultDigits)",
                                  timeZone: .current)

if let _ = inputValue.range(of: #"^\d{2}/\d{2}/\d{4}$"#, options: .regularExpression),
   let dateOfBirth = try? Date(inputValue, strategy: strategy) {
    print("Valid date \(dateOfBirth)")
}
else {
    print("Invalid date")
}

In iOS 16 / macOS 10.13 the regex validation will be included in ParseStrategy.

Upvotes: 1

valeCocoa
valeCocoa

Reputation: 344

Do not mistake the string you use as format of the date formatter for a regular expression. This would have also worked if the parsed string used the “-“ as separator between the date components.

Upvotes: 0

Related Questions