When retrieving birthday from the Facebook SDK i get this string "01/12/1990".
My question is, how would you convert the birthday into the age of the user using this string?
Swift 4
My use case is also for Facebook and I have used UserDefaults to store the birthdate. The below function will retrieve birthdate from UserDefaults, as returned by the graphRequest which is in the same format as your Date. The function will return an Integer with the user's age.
func getAgeFromBirthdate() -> Int {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yyyy"
let birthday = UserDefaults.standard.object(forKey: "birthday")
let birthdayString = birthday as! String
let birthdate = dateFormatter.date(from: birthdayString)
let currentDate = Date()
let calendar: Calendar = Calendar(identifier: .gregorian)
let age = calendar.component(.year, from: birthdate!).distance(to: calendar.component(.year, from: currentDate))
return age
}
func yearsBetween(date1: Date, date2: Date) -> Int {
let calendar = Calendar.current
let components = calendar.dateComponents([Calendar.Component.year], from: date1, to: date2)
return components.year ?? 0
}
// Get Age
let dateString = "01/12/1990"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
let date1 = dateFormatter.date(from: dateString)
let date2 = Date()
let age = self.daysBetween(date1:date1!, date2:date2)
Hope it will help you.
You can do a little more Google before ask, also you may find these answers helpful:
How do you create a swift Date object
Calculate age from birth date using NSDateComponents in Swift
func calcAge(birthday:String) -> Int {
let dateFormater = DateFormatter()
dateFormater.dateFormat = "MM/dd/yyyy"
let birthdayDate = dateFormater.date(from: birthday)
let calendar: NSCalendar! = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)
let now: NSDate! = NSDate()
let calcAge = calendar.components(.year, from: birthdayDate!, to: now as Date, options: [])
let age = calcAge.year
return age!
}
usage:
print(calcAge(birthday: "01/12/1990"))
Related
I am getting a string from API containing date and time as:
createdAt = "2019-08-12T10:34:05.000Z"
I need to extract date from this string and time also.
And how can I get difference as time between two given date strings?
e.g. If I have two strings as:
StartedOn = "2019-08-12T10:32:18.000Z"
StopedOn = "2019-08-12T10:34:05.000Z".
How to get time from start to stop.
swift 4, Xcode 10
Use DateFormatter to get the Date instance from the String, i.e.
let str = "2019-08-12T10:34:05.000Z"
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = formatter.date(from: str)
Now, to get the time difference use timeIntervalSince(_:) with the 2 Date objects, i.e.
let startedOn = "2019-08-12T10:32:18.000Z"
let stoppedOn = "2019-08-12T10:34:05.000Z"
if let startedOnDate = formatter.date(from: startedOn), let stoppedOnDate = formatter.date(from: stoppedOn) {
let timeInterval = stoppedOnDate.timeIntervalSince(startedOnDate)
print(timeInterval)
}
In case you need more detailed components between 2 Date objects, use Calendar object like so,
if let startedOnDate = formatter.date(from: startedOn), let stoppedOnDate = formatter.date(from: stoppedOn) {
let calendar = Calendar(identifier: .gregorian)
let components = calendar.dateComponents([.hour, .minute, .second], from: startedOnDate, to: stoppedOnDate)
print(components) //hour: 0 minute: 1 second: 47
}
Edit:
To get the date and time separately from Date object,
let str = "2019-08-12T10:34:05.000Z"
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if let date = formatter.date(from: str) {
formatter.dateFormat = "hh:mm:ss a"
let timeStr = formatter.string(from: date)
print(timeStr) //add timeStr to your timeLabel here...
formatter.dateFormat = "yyyy-MM-dd"
let dateStr = formatter.string(from: date)
print(dateStr) //add dateStr to your dateLabel here...
}
Try with this :D
import datetime
StartedOn = "2019-08-12T10:32:18.000Z"
StopedOn = "2019-08-12T10:34:05.000Z"
StartedOn = datetime.datetime.fromisoformat(StartedOn[:-1])
StoppedOn = datetime.datetime.fromisoformat(StopedOn[:-1])
print(StoppedOn - StartedOn)
There are two dedicated date formatters for that purpose, ISO8601DateFormatter to convert the ISO8601 string to Date
let isoFormatter = ISO8601DateFormatter()
isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
let createdAtDate = isoFormatter.date(from: "2019-08-12T10:34:05.000Z")
let startedOn = "2019-08-12T10:32:18.000Z"
let stopedOn = "2019-08-12T10:34:05.000Z"
let startedOnDate = isoFormatter.date(from: startedOn)!
let stopedOnDate = isoFormatter.date(from: stopedOn)!
and DateComponentsFormatter to get a m:ss string from the difference between start and end date
let componentsFormatter = DateComponentsFormatter()
componentsFormatter.allowedUnits = [.minute, .second]
let duration = componentsFormatter.string(from: startedOnDate, to: stopedOnDate)
I am trying calculate the age from birthday Date in Swift with this function: (want to write in a textField and pass this data from VC in a Label)
{
var a = self.dob.text
var c = a!.components(separatedBy: "-")
var y1 = c[2]
let cal = NSCalendar? = NSCalendar(calendarIdentifier: .gregorian)
let now = Date()
let year = Calendar.components(.year, from: dob!, to: now, options: [])
let age = (year!) - Int(y1)!
self.myage.text = String(age)
}
But I get an error cannot assign NSCalendar?.Type, but I don't know why get this error (its my first time coding)
You have a few problems in your code. First there is a type as already mentioned by Qi Hao, second you are passing dob is a text field you and Calendar components method expects two dates, so you should first parse the text field date then you can get the year component difference from input date and now:
Playground Testing
let dob = UITextField()
dob.text = "03-27-2002"
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "MM-dd-yyyy"
if let date = dateFormatter.date(from: dob.text!) {
let age = Calendar.current.dateComponents([.year], from: date, to: Date()).year!
print(age) // 16
}
func age(on baseDate: DateComponents) -> Int {
if baseDate.month > month {
return baseDate.year - year
}
if baseDate.month == month && baseDate.day >= day {
return baseDate.year - year
}
return baseDate.year - year - 1
}
try this:
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!
}
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?
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!
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"))
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")
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)")
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
//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()
}
}
Get today's date and your birthday date
let today = Date()
let birthDate = "1990-01-01".getDate(format: "yyyy-MM-dd")
Create an instance of the user's current calendar
let calendar = Calendar.current
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
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))
I understand how to use an NSDateFormatter to convert a month component into a long name string, but how does one convert a month name to an int?
I've been using a switch statement to convert, but I'm thinking there must be a simpler way.
For example, I'd like to convert "May" to 5.
You can use DateFormatter custom format "LLLL" to parse your date string (Month). If you are only parsing dates in english you should set the date formatter locale to "en_US_POSIX":
let df = DateFormatter()
df.locale = Locale(identifier: "en_US_POSIX")
df.dateFormat = "LLLL" // if you need 3 letter month just use "LLL"
if let date = df.date(from: "May") {
let month = Calendar.current.component(.month, from: date)
print(month) // 5
}
Thanks Josh. I've converted the Obj-C code and posted it below for future reference:
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
let components = NSDateComponents()
let formatter = NSDateFormatter()
formatter.dateFormat = "MMMM"
let aDate = formatter.dateFromString("May")
let components1 = calendar!.components(.CalendarUnitMonth , fromDate: aDate!)
let monthInt = components.month
Use MM for the month format. Use stringFromDate to convert your NSDate to a String. Then convert your string to an Int with .toInt()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM"
let monthString = dateFormatter.stringFromDate(NSDate()) // "05"
let monthInt = monthString.toInt() // 5
NSDateFormatter has monthSymbols property. Try:
let formatter = NSDateFormatter()
formatter.calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
let monthString = "September"
let month = find(formatter.monthSymbols as! [String], monthString).map { $0 + 1 }
// -> Optional(9)
let monthString2 = "Foobar"
let month2 = find(formatter.monthSymbols as! [String], monthString2).map { $0 + 1 }
// -> nil
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?
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!
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"))
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")
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)")
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
//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()
}
}
Get today's date and your birthday date
let today = Date()
let birthDate = "1990-01-01".getDate(format: "yyyy-MM-dd")
Create an instance of the user's current calendar
let calendar = Calendar.current
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
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))