I'm building an app that requires me to show time and day i.e Sunday if the object was created prior to 24hrs etc. Just like Message and Mail app in iOS would show time for 24Hrs and than change it to show days like 'monday, tuesday..". I was looking if i can find any framework that does exactly like this or do i have to write a code for this?
-
i can't i just need to show it in a TableViewCell, just like Mail and Message apps in iOS – DevCali Jan 20 '14 at 18:45
-
Just use one of two possible date formats (`NSDateFormatter`) depending on how recent the date is. – rmaddy Jan 20 '14 at 18:46
-
@rmaddy i think your comment makes more sense. i have so far this code that gives me the time only. how can i use this time to know if it was prior to 24hrs and if yes, how do i get the days like Monday, tuesday? if you could please answer with with some example, that would be great. NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; [dateFormatter setDateFormat:@"HH:mm:ss"]; NSString *timeStampStr = [dateFormatter stringFromDate:someObj.timeStamp]; – DevCali Jan 20 '14 at 19:31
8 Answers
Here's how to do it all natively with Swift 4 & 5:
extension Date {
func formatRelativeString() -> String {
let dateFormatter = DateFormatter()
let calendar = Calendar(identifier: .gregorian)
dateFormatter.doesRelativeDateFormatting = true
if calendar.isDateInToday(self) {
dateFormatter.timeStyle = .short
dateFormatter.dateStyle = .none
} else if calendar.isDateInYesterday(self){
dateFormatter.timeStyle = .none
dateFormatter.dateStyle = .medium
} else if calendar.compare(Date(), to: self, toGranularity: .weekOfYear) == .orderedSame {
let weekday = calendar.dateComponents([.weekday], from: self).weekday ?? 0
return dateFormatter.weekdaySymbols[weekday-1]
} else {
dateFormatter.timeStyle = .none
dateFormatter.dateStyle = .short
}
return dateFormatter.string(from: self)
}
}

- 2,292
- 2
- 18
- 33
I needed this too, so I wrote the following NSDate extension:
extension NSDate {
func formattedRelativeString() -> String {
let dateFormatter = NSDateFormatter()
dateFormatter.doesRelativeDateFormatting = true
if isToday() {
dateFormatter.timeStyle = .ShortStyle
dateFormatter.dateStyle = .NoStyle
} else if isYesterday() {
dateFormatter.timeStyle = .NoStyle
dateFormatter.dateStyle = .MediumStyle
} else if daysAgo() < 6 {
return dateFormatter.weekdaySymbols[weekday()-1]
} else {
dateFormatter.timeStyle = .NoStyle
dateFormatter.dateStyle = .ShortStyle
}
return dateFormatter.stringFromDate(self)
}
}
This requires Matthew York's excellent DateTools to work.

- 858
- 11
- 24
Swift 3 version of @avf response:
extension NSDate {
func formattedRelativeString() -> String
{
let dateFormatter = DateFormatter()
dateFormatter.doesRelativeDateFormatting = true
if isToday() {
dateFormatter.timeStyle = .short
dateFormatter.dateStyle = .none
} else if isYesterday() {
dateFormatter.timeStyle = .none
dateFormatter.dateStyle = .medium
} else if daysAgo() < 6 {
return dateFormatter.weekdaySymbols[weekday()-1]
} else {
dateFormatter.timeStyle = .none
dateFormatter.dateStyle = .short
}
return dateFormatter.string(from: self as Date)
}
}

- 1
- 1

- 633
- 6
- 9
updated for swift 4:
extension NSDate {
func formattedRelativeString() -> String
{
let dateFormatter = DateFormatter()
if isInToday || isInYesterday {
/// today and yesterday
/// Today, 3:57 PM
dateFormatter.doesRelativeDateFormatting = true
dateFormatter.timeStyle = .short
dateFormatter.dateStyle = .short
} else if isLessThanAweekAgo {
/// less than a week ago
/// Friday, 4:03 PM
dateFormatter.dateFormat = "EEEE, h:mm a"
} else if isInThisYear {
// more than a week ago
// Fri, 4 Aug, 3:55
dateFormatter.dateFormat = "E, d MMM, h:mm a"
} else {
// more than a year ago
// Aug 10, 2016, 3:56
dateFormatter.dateFormat = "MMM d, yyyy, h:mm a"
}
return dateFormatter.string(from: self)
}
}
you can test it in playground with these sample dates:
let now = Date()
let yesterday = Date(timeInterval: -24*60*60, since: Date())
let weekAgo = Date(timeInterval: -7*24*60*60, since: Date())
let yearAgo = Date(timeInterval: -366*24*60*60, since: Date())

- 13,077
- 8
- 66
- 75
NSString *dateString = [NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterFullStyle];
NSLog(@"%@",dateString);
Try this code, modify it as per your requirement.

- 1,392
- 23
- 37
Objective C formating date and time.
Using Matthew York's excellent DateTools methods.
NSDate extension:
-(NSString *)formatDateTimeToString{
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setLocale: [[NSLocale alloc] initWithLocaleIdentifier: [[NSLocale currentLocale] localeIdentifier]]];
if ([[NSCalendar currentCalendar] isDateInToday:self])
{
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterNoStyle];
}
else if ([[NSCalendar currentCalendar] isDateInYesterday:self])
{
[dateFormatter setDoesRelativeDateFormatting:YES];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
}
else if ([self daysAgo]<6)
{
[dateFormatter setDateFormat:@"EEEE"];
}
else
{
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
}
return [dateFormatter stringFromDate:self];
}
-(NSInteger)daysAgo{
return [self daysEarlierThan:[NSDate date]];
}
-(NSInteger)daysEarlierThan:(NSDate *)date{
return ABS(MIN([self daysFrom:date], 0));
}
-(NSInteger)daysFrom:(NSDate *)date{
return [self daysFrom:date calendar:nil];
}
-(NSInteger)daysFrom:(NSDate *)date calendar:(NSCalendar *)calendar{
NSDate *earliest = [self earlierDate:date];
NSDate *latest = (earliest == self) ? date : self;
NSInteger multiplier = (earliest == self) ? -1 : 1;
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay fromDate:earliest toDate:latest options:0];
return multiplier*components.day;
}

- 153
- 1
- 9
I have tried all the above solutions but unfortunately, nothing worked for me. Anyway, I ended up with a solution.
Swift version
extension Date {
func isEqual(to date: Date, toGranularity component: Calendar.Component, in calendar: Calendar = .current) -> Bool {
calendar.isDate(self, equalTo: date, toGranularity: component)
}
func isInSameYear(as date: Date) -> Bool { isEqual(to: date, toGranularity: .year) }
func isInSameMonth(as date: Date) -> Bool { isEqual(to: date, toGranularity: .month) }
func isInSameWeek(as date: Date) -> Bool { isEqual(to: date, toGranularity: .weekOfYear) }
func isInSameDay(as date: Date) -> Bool { Calendar.current.isDate(self, inSameDayAs: date) }
var isInThisYear: Bool { isInSameYear(as: Date()) }
var isInThisMonth: Bool { isInSameMonth(as: Date()) }
var isInThisWeek: Bool { isInSameWeek(as: Date()) }
var isInYesterday: Bool { Calendar.current.isDateInYesterday(self) }
var isInToday: Bool { Calendar.current.isDateInToday(self) }
var isInTomorrow: Bool { Calendar.current.isDateInTomorrow(self) }
var isInTheFuture: Bool { self > Date() }
var isInThePast: Bool { self < Date() }
func formattedRelativeString() -> String {
let dateFormatter = DateFormatter()
if self.addingTimeInterval(60) > Date() {
// less than a minute
return "Now"
} else if isInToday || isInYesterday {
// today and yesterday
// Today, 3:57 PM
dateFormatter.doesRelativeDateFormatting = true
dateFormatter.timeStyle = .short
dateFormatter.dateStyle = .short
} else if isInThisWeek {
// less than a week ago
// Friday, 4:03 PM
dateFormatter.dateFormat = "EEEE, h:mm a"
} else if isInThisYear {
// more than a week ago
// Fri, 4 Aug, 3:55 AM
dateFormatter.dateFormat = "E, d MMM, h:mm a"
} else {
// more than a year ago
// 10 Aug, 2016, 3:56 AM
dateFormatter.dateFormat = "d MMM, yyyy, h:mm a"
}
return dateFormatter.string(from: self)
}
}
You can change the date format for each according to your needs. To create your own customized date format refer to this article.
Output
let now = Date().formattedRelativeString()
// Now
let today = Date(timeInterval: -60*60, since: Date()).formattedRelativeString()
// Today, 9:06 AM
let yesterday = Date(timeInterval: -24*60*60, since: Date()).formattedRelativeString()
// Yesterday, 10:06 AM
let weekAgo = Date(timeInterval: -7*24*60*60, since: Date()).formattedRelativeString()
// Fri, 28 Jul, 10:06 AM
let yearAgo = Date(timeInterval: -366*24*60*60, since: Date()).formattedRelativeString()
// 3 Aug, 2022, 10:06 AM

- 1,579
- 13
- 19
Use a NSDateFormatter and set it's doesRelativeDateFormatting
property to YES.

- 578
- 2
- 9
-
-
NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; formatter.doesRelativeDateFormatting = YES; See https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSDateFormatter_Class/Reference/Reference.html – rist Jan 20 '14 at 19:06