0

In my code below i have implemented a date picker to be the subview of my textfield. I am stuck on the function; 'verifyAge'. The if statement in the function is working fine and will change the textField colour when the Date Picker date is above or below the specified date. But it only works to the corresponding year But does not Work to the exact Day. I have tried searching for the past two days and couldn't find a solution to my exact problem.

 class AgeConfirmViewController: UIViewController, UITextFieldDelegate   {

@IBOutlet weak var txtAgeConfirmation: UITextField!
let datePicker: UIDatePicker = UIDatePicker()

 override func viewDidLoad() {
    super.viewDidLoad()
    txtAgeConfirmation.delegate = self
    createDatePicker()
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
    txtAgeConfirmation.inputView = datePicker
    datePicker.addTarget(self, action: #selector(self.datePickerChanged(sender:)), for: .valueChanged)
 }



   func datePickerChanged(sender: UIDatePicker) {
    let formatter = DateFormatter()
    formatter.timeStyle = .none
    formatter.dateStyle = .long
    txtAgeConfirmation.text = formatter.string(from: sender.date)
    verifyAge()
}


  func createDatePicker() {
    datePicker.datePickerMode = .date
    datePicker.maximumDate = Calendar.current.date(byAdding: .year, value: 0, to: Date())
}


 func verifyAge() {

    let dateOfBirth = datePicker.date
    let today = Date()
    let gregorian = NSCalendar(identifier: NSCalendar.Identifier.gregorian)
    let age = gregorian?.components([.month, .day, .year], from: dateOfBirth, to: today, options:[])

      if (age?.year)! < 21 {


        txtAgeConfirmation.textColor = UIColor.red

    } else if (age?.year)! > 21 {

        txtAgeConfirmation.textColor = UIColor.black

    }
}
vadian
  • 274,689
  • 30
  • 353
  • 361
pjunior
  • 78
  • 1
  • 8
  • Please clarify if you need it to be down to the day. Meaning if the age is 19y 11hr 59m they do not meat the age of 20y. In stead you you are getting is if they will be 20y in this year but are not 20y yet. – MwcsMac Jan 06 '17 at 19:06
  • It is clarified. 'it only works to the corresponding year But does not Work to the exact Day'. I want it to be to the exact day yes. – pjunior Jan 06 '17 at 19:09
  • Try this code: http://stackoverflow.com/questions/27182023/getting-the-difference-between-two-nsdates-in-months-days-hours-minutes-seconds – dahiya_boy Jan 06 '17 at 19:17

1 Answers1

4

Simple solution, ignore day and month:

let gregorian = Calendar(identifier: .gregorian)
let ageComponents = gregorian.dateComponents([.year], from: dateOfBirth, to: Date())
let age = ageComponents.year!

txtAgeConfirmation.textColor = age < 21 ? .red : .black

Or if you want to ignore the time

let ageComponents = calendar.dateComponents([.year], from: calendar.startOfDay(for: dateOfBirth), to: calendar.startOfDay(for: Date()))

In Swift 3 there are less question and exclamation marks by using native Calendar struct.
The age exclamation mark after year is absolutely safe because the year component is clearly specified.

vadian
  • 274,689
  • 30
  • 353
  • 361
  • xcode prompted me to add the exclamation mark, and i only did have year before submitting this question. I thought adding month and day would solve it but it did not. I just changed it again and the problem is still their.. – pjunior Jan 06 '17 at 19:08
  • I'm not sure what result you're expecting, I updated the answer with an alternative. – vadian Jan 06 '17 at 19:15
  • Adding the code you updated helped, i was missing the from the 'startOfDay', Thanks – pjunior Jan 06 '17 at 19:31