49

I am trying calculate the age from birthdayDate in Swift with this function:

var calendar : NSCalendar = NSCalendar.currentCalendar()

var dateComponentNow : NSDateComponents = calendar.components(
             NSCalendarUnit.CalendarUnitYear, 
             fromDate: birthday, 
             toDate: age, 
             options: 0)

But I get an error Extra argument toDate in call

In objective c this was the code, but I don't know why get this error:

NSDate* birthday = ...;

NSDate* now = [NSDate date];
NSDateComponents* ageComponents = [[NSCalendar currentCalendar] 
                               components:NSYearCalendarUnit 
                               fromDate:birthday
                               toDate:now
                               options:0];
NSInteger age = [ageComponents year]; 

Is there correct form better than this?

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
user3745888
  • 6,143
  • 15
  • 48
  • 97

7 Answers7

92

You get an error message because 0 is not a valid value for NSCalendarOptions. For "no options", use NSCalendarOptions(0) or simply nil:

let ageComponents = calendar.components(.CalendarUnitYear,
                              fromDate: birthday,
                                toDate: now,
                               options: nil)
let age = ageComponents.year

(Specifying nil is possible because NSCalendarOptions conforms to the RawOptionSetType protocol which in turn inherits from NilLiteralConvertible.)

Update for Swift 2:

let ageComponents = calendar.components(.Year,
    fromDate: birthday,
    toDate: now,
    options: [])

Update for Swift 3:

Assuming that the Swift 3 types Date and Calendar are used:

let now = Date()
let birthday: Date = ...
let calendar = Calendar.current

let ageComponents = calendar.dateComponents([.year], from: birthday, to: now)
let age = ageComponents.year!
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • @NaveedKhan: Thank you for the edit suggestion. However, the Swift 3 code is correct as it stands if the new `Date` type is used instead of the "old" `NSDate`. Please let me know if there is any problem with it. – Martin R Mar 28 '17 at 11:21
  • please run the command in the second last line of your code in swift 3... 'calendar.datecomponen't is replaced by 'calendar.component' – Naveed Khan Mar 28 '17 at 12:50
  • @NaveedKhan: That is strange. I just double-checked that the Swift 3 code compiles in Xcode 8.2.1 (Swift 3.0) and in Xcode 8.3 (Swift 3.1). Which Xcode version are you using? Did you try the exact code as posted above? – Martin R Mar 28 '17 at 12:53
21

I create this method its very easy just put the birthday date in the method and this will return the Age as a Int

Swift 3

func calcAge(birthday: String) -> Int {
    let dateFormater = DateFormatter()
    dateFormater.dateFormat = "MM/dd/yyyy"
    let birthdayDate = dateFormater.date(from: birthday)
    let calendar: NSCalendar! = NSCalendar(calendarIdentifier: .gregorian)
    let now = Date()
    let calcAge = calendar.components(.year, from: birthdayDate!, to: now, options: [])
    let age = calcAge.year
    return age!
}

Swift 2

func calcAge(birthday: String) -> Int{
    let dateFormater = NSDateFormatter()
    dateFormater.dateFormat = "MM/dd/yyyy"
    let birthdayDate = dateFormater.dateFromString(birthday)
    let calendar: NSCalendar! = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
    let now: NSDate! = NSDate()
    let calcAge = calendar.components(.Year, fromDate: birthdayDate!, toDate: now, options: [])
    let age = calcAge.year
    return age
}

Usage

print(calcAge("06/29/1988"))
Cœur
  • 37,241
  • 25
  • 195
  • 267
Gal Mesika
  • 311
  • 2
  • 6
  • Hey thx for your code, it doesn't work on Swift 3.0 anymore. Can you maybe post an updated version? It helped me in my App. – makle Sep 21 '16 at 22:50
  • @Dug, thank you for noticing the difference in `dateFormat`. Yet, you did not perfectly kept identical behavior between the two pieces of code, as you left `YYYY` for one and `yyyy` for the other. Quoting Apple: ["_It uses yyyy to specify the year component. A common mistake is to use YYYY. yyyy specifies the calendar year whereas YYYY specifies the year (of “Week of Year”), used in the ISO year-week calendar._"](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW1) – Cœur Aug 28 '17 at 03:45
  • Thanks for the info, I had the wrong year format in my project as well – Dug Aug 30 '17 at 00:04
10

For swift 4 works fine

func getAgeFromDOF(date: String) -> (Int,Int,Int) {

    let dateFormater = DateFormatter()
    dateFormater.dateFormat = "YYYY-MM-dd"
    let dateOfBirth = dateFormater.date(from: date)

    let calender = Calendar.current

    let dateComponent = calender.dateComponents([.year, .month, .day], from: 
    dateOfBirth!, to: Date())

    return (dateComponent.year!, dateComponent.month!, dateComponent.day!)
}

let age  = getAgeFromDOF(date: "2000-12-01")

print("\(age.0) Year, \(age.1) Month, \(age.2) Day")
Bola Ibrahim
  • 720
  • 9
  • 8
3

This works for Swift 3

let myDOB = Calendar.current.date(from: DateComponents(year: 1994, month: 9, day: 10))!
let myAge = Calendar.current.dateComponents([.month], from: myDOB, to: Date()).month!
let years = myAge / 12
let months = myAge % 12
print("Age : \(years).\(months)")
A. Pooja
  • 39
  • 6
1

This is working in swift 3 for me..

let now = NSDate()
    let calendar : NSCalendar = NSCalendar.current as NSCalendar
    let ageComponents = calendar.components(.year, from: datePickerView.date, to: now as Date, options: [])
    let age = ageComponents.year!
    ageCalculated.text = String(age)

Thanks to @Martin R

Narasimha Nallamsetty
  • 1,215
  • 14
  • 16
1

This is the best way on swift 5

lazy var dateFormatter : DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        formatter.locale = Locale(identifier: "en_US_POSIX")
        return formatter
    }()

let birthday = dateFormatter.date(from: "1980-04-25")
let timeInterval = birthday?.timeIntervalSinceNow
let age = abs(Int(timeInterval! / 31556926.0))
  • Works fine for me in playground. Just going to make a var and connect to a date picker and link it to where the date of birth is in the above code. Thank you! – David_2877 Sep 21 '20 at 12:57
1

//Create string extension to make more easy

extension String {
            func getDate(format: String) -> Date {
                let dateFormatter = DateFormatter()
                dateFormatter.dateFormat = format
                dateFormatter.locale = Locale(identifier: "en_US_POSIX")
                return dateFormatter.date(from: self) ?? Date()
            } 
        }
  1. Get today's date and your birthday date

let today = Date()

let birthDate = "1990-01-01".getDate(format: "yyyy-MM-dd")

  1. Create an instance of the user's current calendar

let calendar = Calendar.current

  1. Use calendar to get difference between two dates

let components = calendar.dateComponents([.year, .month, .day], from: birthDate, to: today)

let ageYears = components.year //get how many years old

let ageMonths = components.month //extra months

let ageDays = components.day // extra days

sudayn
  • 1,169
  • 11
  • 14