NSDate
NSDateFormatter
Section titled “NSDateFormatter”Converting an NSDate object to string is just 3 steps.
1. Create an NSDateFormatter object
Section titled “1. Create an NSDateFormatter object”let dateFormatter = NSDateFormatter()Swift 3
Section titled “Swift 3”let dateFormatter = DateFormatter()Objective-C
Section titled “Objective-C”NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];2. Set the date format in which you want your string
Section titled “2. Set the date format in which you want your string”dateFormatter.dateFormat = "yyyy-MM-dd 'at' HH:mm"Objective-C
Section titled “Objective-C”dateFormatter.dateFormat = @"yyyy-MM-dd 'at' HH:mm";3. Get the formatted string
Section titled “3. Get the formatted string”let date = NSDate() // your NSDate objectlet dateString = dateFormatter.stringFromDate(date)Swift 3
Section titled “Swift 3”let date = Date() // your NSDate objectlet dateString = dateFormatter.stringFromDate(date)Objective-C
Section titled “Objective-C”NSDate *date = [NSDate date]; // your NSDate objectNSString *dateString = [dateFormatter stringFromDate:date];This will give output something like this: 2001-01-02 at 13:00
Note
Creating an `NSDateFormatter` instance is an expensive operation, so it is recommended to create it once and reuse when possible.Useful extension for converting date to string.
Section titled “Useful extension for converting date to string.”extension Date { func toString() -> String { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "MMMM dd yyyy" return dateFormatter.string(from: self) }}Useful links for swift date-formation swiftly-getting-human-readable-date-nsdateformatter.
For constructing date formats see date format patterns.
Date Comparison
Section titled “Date Comparison”There are 4 methods for comparing dates:
isEqualToDate(anotherDate: NSDate) -> BoolearlierDate(anotherDate: NSDate) -> NSDatelaterDate(anotherDate: NSDate) -> NSDatecompare(anotherDate: NSDate) -> NSComparisonResult
Objective-C
Section titled “Objective-C”- (BOOL)isEqualToDate:(NSDate *)anotherDate- (NSDate *)earlierDate:(NSDate *)anotherDate- (NSDate *)laterDate:(NSDate *)anotherDate- (NSComparisonResult)compare:(NSDate *)anotherDate
Let’s say we have 2 dates:
let date1: NSDate = ... // initialized as July 7, 2016 00:00:00let date2: NSDate = ... // initialized as July 2, 2016 00:00:00Objective-C
Section titled “Objective-C”NSDate *date1 = ... // initialized as July 7, 2016 00:00:00NSDate *date2 = ... // initialized as July 2, 2016 00:00:00Then, to compare them, we try this code:
if date1.isEqualToDate(date2) { // returns false, as both dates aren't equal}
earlierDate: NSDate = date1.earlierDate(date2) // returns the earlier date of the two (date 2)laterDate: NSDate = date1.laterDate(date2) // returns the later date of the two (date1)
result: NSComparisonResult = date1.compare(date2)
if result == .OrderedAscending { // true if date1 is earlier than date2} else if result == .OrderedSame { // true if the dates are the same} else if result == .OrderedDescending { // true if date1 is later than date1}Objective-C
Section titled “Objective-C”if ([date1 isEqualToDate:date2]) { // returns false, as both date are not equal}
NSDate *earlierDate = [date1 earlierDate:date2]; // returns date which comes earlier from both date, here it will return date2NSDate *laterDate = [date1 laterDate:date2]; // returns date which comes later from both date, here it will return date1
NSComparisonResult result = [date1 compare:date2];if (result == NSOrderedAscending) { // fails // comes here if date1 is earlier then date2, in our case it will not come here} else if (result == NSOrderedSame){ // fails // comes here if date1 is same as date2, in our case it will not come here} else{ // NSOrderedDescending // succeeds // comes here if date1 is later than date2, in our case it will come here}If you want to compare dates and handle seconds, weeks, months and years:
Swift 3
Section titled “Swift 3”let dateStringUTC = "2016-10-22 12:37:48 +0000"let dateFormatter = DateFormatter()dateFormatter.locale = Locale(identifier: "en_US_POSIX")dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss X"let date = dateFormatter.date(from: dateStringUTC)!
let now = Date()
let formatter = DateComponentsFormatter()formatter.unitsStyle = .fullformatter.maximumUnitCount = 2let string = formatter.string(from: date, to: Date())! + " " + NSLocalizedString("ago", comment: "added after elapsed time to say how long before")Or you can use this for each component:
// get the current date and timelet currentDateTime = Date()
// get the user's calendarlet userCalendar = Calendar.current
// choose which date and time components are neededlet requestedComponents: Set<Calendar.Component> = [ .year, .month, .day, .hour, .minute, .second]
// get the componentslet dateTimeComponents = userCalendar.dateComponents(requestedComponents, from: currentDateTime)
// now the components are availabledateTimeComponents.yeardateTimeComponents.monthdateTimeComponents.daydateTimeComponents.hourdateTimeComponents.minutedateTimeComponents.secondGet Historic Time from NSDate (eg: 5s ago, 2m ago, 3h ago)
Section titled “Get Historic Time from NSDate (eg: 5s ago, 2m ago, 3h ago)”This can be used in various chat applications, rss feeds, and social apps where you need to have latest feeds with timestamps:
Objective-C
Section titled “Objective-C”- (NSString *)getHistoricTimeText:(NSDate *)since{ NSString *str; NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:since]; if(interval < 60) str = [NSString stringWithFormat:@"%is ago",(int)interval]; else if(interval < 3600) { int minutes = interval/60; str = [NSString stringWithFormat:@"%im ago",minutes]; } else if(interval < 86400) { int hours = interval/3600;
str = [NSString stringWithFormat:@"%ih ago",hours]; } else { NSDateFormatter *dateFormater=[[NSDateFormatter alloc]init]; [dateFormater setLocale:[NSLocale currentLocale]]; NSString *dateFormat = [NSDateFormatter dateFormatFromTemplate:@"MMM d, YYYY" options:0 locale:[NSLocale currentLocale]]; [dateFormater setDateFormat:dateFormat]; str = [dateFormater stringFromDate:since];
} return str;}Get Unix Epoch time
Section titled “Get Unix Epoch time”To get Unix Epoch Time, use the constant timeIntervalSince1970:
let date = NSDate() // current datelet unixtime = date.timeIntervalSince1970Objective-C
Section titled “Objective-C”NSDate *date = [NSDate date]; // current dateint unixtime = [date timeIntervalSince1970];Get time cycle type (12-hour or 24-hour)
Section titled “Get time cycle type (12-hour or 24-hour)”Checking whether the current date contains the symbol for AM or PM
Section titled “Checking whether the current date contains the symbol for AM or PM”Objective-C
Section titled “Objective-C”NSDateFormatter *formatter = [[NSDateFormatter alloc] init];[formatter setLocale:[NSLocale currentLocale]];[formatter setDateStyle:NSDateFormatterNoStyle];[formatter setTimeStyle:NSDateFormatterShortStyle];NSString *dateString = [formatter stringFromDate:[NSDate date]];NSRange amRange = [dateString rangeOfString:[formatter AMSymbol]];NSRange pmRange = [dateString rangeOfString:[formatter PMSymbol]];BOOL is24h = (amRange.location == NSNotFound && pmRange.location == NSNotFound);Requesting the time cycle type from NSDateFormatter
Section titled “Requesting the time cycle type from NSDateFormatter”Objective-C
Section titled “Objective-C”NSString *formatStringForHours = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]];NSRange containsA = [formatStringForHours rangeOfString:@"a"];BOOL is24h = containsA.location == NSNotFound;This uses a special date template string called “j” which according to the ICU Spec …
[...] requests the preferred hour format for the locale (h, H, K, or k), as determined by the preferred attribute of the hours element in supplemental data. [...] Note that use of 'j' in a skeleton passed to an API is the only way to have a skeleton request a locale's preferred time cycle type (12-hour or 24-hour).
That last sentence is important. It “is the only way to have a skeleton request a locale’s preferred time cycle type”. Since NSDateFormatter and NSCalendar are built on the ICU library, the same holds true here.
Reference
The second option was derived from [this answer](http://stackoverflow.com/a/11660380/410143).Get NSDate from JSON Date format “/Date(1268123281843)/”
Section titled “Get NSDate from JSON Date format “/Date(1268123281843)/””Prior to Json.NET 4.5 dates were written using the Microsoft format: “/Date(1198908717056)/”. If your server sends date in this format you can use the below code to serialize it to NSDate:
Objective-C
Section titled “Objective-C”(NSDate*) getDateFromJSON:(NSString *)dateString{ // Expect date in this format "/Date(1268123281843)/" int startPos = [dateString rangeOfString:@"("].location+1; int endPos = [dateString rangeOfString:@")"].location; NSRange range = NSMakeRange(startPos,endPos-startPos); unsigned long long milliseconds = [[dateString substringWithRange:range] longLongValue]; NSLog(@"%llu",milliseconds); NSTimeInterval interval = milliseconds/1000; NSDate *date = [NSDate dateWithTimeIntervalSince1970:interval]; // add code for date formatter if need NSDate in specific format. return date;}Get Current Date
Section titled “Get Current Date”Getting current date is very easy. You get NSDate object of current date in just single line as follows:
var date = NSDate()Swift 3
Section titled “Swift 3”var date = Date()Objective-C
Section titled “Objective-C”NSDate *date = [NSDate date];Get NSDate Object N seconds from current date
Section titled “Get NSDate Object N seconds from current date”The number of seconds from the current date and time for the new date. Use a negative value to specify a date before the current date.
For doing this we have a method named dateWithTimerIntervalSinceNow(seconds: NSTimeInterval) -> NSDate (Swift) or + (NSDate*)dateWithTimeIntervalSinceNow:(NSTimeInterval)seconds (Objective-C).
Now for example, if you require a date one week from current date and one week to current date, then we can do it as.
let totalSecondsInWeek:NSTimeInterval = 7 * 24 * 60 * 60;//Using negative value for previous date from todaylet nextWeek = NSDate().dateWithTimerIntervalSinceNow(totalSecondsInWeek)
//Using positive value for future date from todaylet lastWeek = NSDate().dateWithTimerIntervalSinceNow(-totalSecondsInWeek)Swift 3
Section titled “Swift 3”let totalSecondsInWeek:TimeInterval = 7 * 24 * 60 * 60;
//Using positive value to add to the current datelet nextWeek = Date(timeIntervalSinceNow: totalSecondsInWeek)
//Using negative value to get date one week from current datelet lastWeek = Date(timeIntervalSinceNow: -totalSecondsInWeek)Objective-C
Section titled “Objective-C”NSTimeInterval totalSecondsInWeek = 7 * 24 * 60 * 60;//Using negative value for previous date from todayNSDate *lastWeek = [NSDate dateWithTimeIntervalSinceNow:-totalSecondsInWeek];
//Using positive value for future date from todayNSDate *nextWeek = [NSDate dateWithTimeIntervalSinceNow:totalSecondsInWeek];
NSLog(@"Last Week: %@", lastWeek);NSLog(@"Right Now: %@", now);NSLog(@"Next Week: %@", nextWeek);Convert NSDate that is composed from hour and minute (only) to a full NSDate
Section titled “Convert NSDate that is composed from hour and minute (only) to a full NSDate”There are many cases when one has created an NSDate from only an hour and minute format, i.e: 08:12 that returns from a server as a String and you initiate an NSDate instance by these values only.
The downside for this situation is that your NSDate is almost completely “naked” and what you need to do is to create: day, month, year, second and time zone in order to this object to “play along” with other NSDate types.
For the sake of the example let’s say that hourAndMinute is the NSDate type that is composed from hour and minute format:
Objective-C
Section titled “Objective-C”NSDateComponents *hourAndMinuteComponents = [calendar components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate:hourAndMinute];NSDateComponents *componentsOfDate = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
NSDateComponents *components = [[NSDateComponents alloc] init];[components setDay: componentsOfDate.day];[components setMonth: componentsOfDate.month];[components setYear: componentsOfDate.year];[components setHour: [hourAndMinuteComponents hour]];[components setMinute: [hourAndMinuteComponents minute]];[components setSecond: 0];[calendar setTimeZone: [NSTimeZone defaultTimeZone]];
NSDate *yourFullNSDateObject = [calendar dateFromComponents:components];Now your object is the total opposite of being “naked”.
UTC Time offset from NSDate with TimeZone
Section titled “UTC Time offset from NSDate with TimeZone”Here this will calculate the UTC time offset from current data in desired timezone.
+(NSTimeInterval)getUTCOffSetIntervalWithCurrentTimeZone:(NSTimeZone *)current forDate:(NSDate *)date { NSTimeZone *utcTimeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; NSInteger currentGMTOffset = [current secondsFromGMTForDate:date]; NSInteger gmtOffset = [utcTimeZone secondsFromGMTForDate:date]; NSTimeInterval gmtInterval = currentGMTOffset - gmtOffset; return gmtInterval;}Syntax
Section titled “Syntax”- NSDate() // NSDate object init to the current date and time
- NSDate().timeIntervalSince1970 // Current date and time in number of seconds from 00:00:00 UTC on 1 January 1970.
- NSDate().compare(other: NSDate) // Returns a comparison of current date to another date returns a
NSComparisonResult
Remarks
Section titled “Remarks”There are different types of date format that you can set: Here is full list of them.
|Format|Meaning/Description|Example1|Example2 |---|---|---|---|---|---|---|---|---|--- |y|A year with at least 1 digit.|175 AD → “175”|2016 AD → “2016” |yy|A year with exactly 2 digits.|5 AD → “05”|2016 AD → “16” |yyy|A year with at least 3 digits.|5 AD → “005”|2016 AD → “2016” |yyyy|A year with at least 4 digits.|5 AD → “0005”|2016 AD → “2016” |M|A month with at least 1 digit.|July → “7”|“November” → “11” |MM|A month with at least 2 digits.|July → “07”|“November” → “11” |MMM|Three letter month abbreviation.|July → “Jul”|“November” → “Nov” |MMMM|Full name of month.|July → “July”|“November” → “November” |MMMMM|One letter month abbreviation(Jan,June,July all will have ‘J’).|July → “J”|“November” → “N” |d|Day with at least one digit.|8 → “8”|29 → “29” |dd|Day with at least two digits.|8 → “08”|29 → “29” |“E”, “EE”, or”EEE”|3 letter day abbreviation of day name.|Monday → “Mon”|Thursday → “Thu” |EEEE|Full Day name.|Monday → “Monday”|Thursday → “Thursday” |EEEEE|1 letter day abbreviation of day name.(Thu and Tue will be ‘T’)|Monday → “M”|Thursday → “T” |EEEEEE|2 letter day abbreviation of day name.|Monday → “Mo”|Thursday → “Th” |a|Period of day (AM/PM).|10 PM → “PM”|2 AM → “AM” |h|A 1-12 based hour with at least 1 digit.|10 PM → “10”|2 AM → “2” |hh|A 1-12 based hour with at least 2 digits.|10 PM → “10”|2 AM → “02” |H|A 0-23 based hour with at least 1 digit.|10 PM → “14”|2 AM → “2” |HH|A 0-23 based hour with at least 2 digits.|10 PM → “14”|2 AM → “02” |m|A minute with at least 1 digit.|7 → “7”|29 → “29” |mm|A minute with at least 2 digits.|7 → “07”|29 → “29” |s|A second with at least 1 digit.|7 → “7”|29 → “29” |ss|A second with at least 2 digits.|7 → “07”|29 → “29”
There are many more, for getting different time based on zone(z), for getting time with millisecond details(S), etc.