Skip to content

Instantly share code, notes, and snippets.

@andatta
Created May 23, 2017 05:46
Show Gist options
  • Save andatta/3b2010604aa4bd553bf0098470f6dbb8 to your computer and use it in GitHub Desktop.
Save andatta/3b2010604aa4bd553bf0098470f6dbb8 to your computer and use it in GitHub Desktop.
Swift code to calculate age in years, months and days from a person's dob
func calculateAge(dob : String) -> (year :Int, month : Int, day : Int){
let df = NSDateFormatter()
df.dateFormat = "yyyy-MM-dd"
let date = df.dateFromString(dob)
guard let val = date else{
return (0, 0, 0)
}
var years = 0
var months = 0
var days = 0
let cal = NSCalendar.currentCalendar()
years = cal.component(.Year, fromDate: NSDate()) - cal.component(.Year, fromDate: val)
let currMonth = cal.component(.Month, fromDate: NSDate())
let birthMonth = cal.component(.Month, fromDate: val)
//get difference between current month and birthMonth
months = currMonth - birthMonth
//if month difference is in negative then reduce years by one and calculate the number of months.
if months < 0
{
years = years - 1
months = 12 - birthMonth + currMonth
if cal.component(.Day, fromDate: NSDate()) < cal.component(.Day, fromDate: val){
months = months - 1
}
} else if months == 0 && cal.component(.Day, fromDate: NSDate()) < cal.component(.Day, fromDate: val)
{
years = years - 1
months = 11
}
//Calculate the days
if cal.component(.Day, fromDate: NSDate()) > cal.component(.Day, fromDate: val){
days = cal.component(.Day, fromDate: NSDate()) - cal.component(.Day, fromDate: val)
}
else if cal.component(.Day, fromDate: NSDate()) < cal.component(.Day, fromDate: val)
{
let today = cal.component(.Day, fromDate: NSDate())
let date = cal.dateByAddingUnit(.Month, value: -1, toDate: NSDate(), options: [])
days = (cal.component(.Day, fromDate: date!) - cal.component(.Day, fromDate: val)) + today
} else
{
days = 0
if months == 12
{
years = years + 1
months = 0
}
}
return (years, months, days)
}
@helenhell
Copy link

helenhell commented Sep 17, 2018

Hi! Thanks for this code, that was very useful for me. But you've kinda got a bug here.

Line 43: cal.component(.day, from: date!) = number of days for the given date, but not the total number of days for the month in a given date as you'd wish.

I fixed it like this (Swift 4):

extension Date{
     var daysInMonth:Int{
        let calendar = Calendar.current
        
        let dateComponents = DateComponents(year: calendar.component(.year, from: self), month: calendar.component(.month, from: self))
        let date = calendar.date(from: dateComponents)!
        
        let range = calendar.range(of: .day, in: .month, for: date)!
        let numDays = range.count
        
        return numDays
    }
}

Line 43:  days = date.daysInMonth - cal.component(.day, from: val) + today

@wilsoncampusano
Copy link

Thankyou!
this is the Swift 4 version. plus that fix from @helenhell

    func calculateAge(dob : String, format:String = "yyyy-MM-dd") -> (year :Int, month : Int, day : Int){
        let df = DateFormatter()
        df.dateFormat = format
        let date = df.date(from: dob)
        guard let val = date else{
            return (0, 0, 0)
        }
        var years = 0
        var months = 0
        var days = 0
        
        let cal = Calendar.current
        years = cal.component(.year, from: Date()) -  cal.component(.year, from: val)
        
        let currMonth = cal.component(.month, from: Date())
        let birthMonth = cal.component(.month, from: val)
        
        //get difference between current month and birthMonth
        months = currMonth - birthMonth
        //if month difference is in negative then reduce years by one and calculate the number of months.
        if months < 0
        {
            years = years - 1
            months = 12 - birthMonth + currMonth
            if cal.component(.day, from: Date()) < cal.component(.day, from: val){
                months = months - 1
            }
        } else if months == 0 && cal.component(.day, from: Date()) < cal.component(.day, from: val)
        {
            years = years - 1
            months = 11
        }
        
        //Calculate the days
        if cal.component(.day, from: Date()) > cal.component(.day, from: val){
            days = cal.component(.day, from: Date()) - cal.component(.day, from: val)
        }
        else if cal.component(.day, from: Date()) < cal.component(.day, from: val)
        {
            let today = cal.component(.day, from: Date())
            let date = cal.date(byAdding: .month, value: -1, to: Date())
            
            days = date!.daysInMonth - cal.component(.day, from: val) + today
        } else
        {
            days = 0
            if months == 12
            {
                years = years + 1
                months = 0
            }
        }
        
        return (years, months, days)
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment