So my intention is to put out dates that would look like the following:
Today, August 28
Tomorrow, August 29
Friday, August 30
...etc
The issue
It seems there is no way to accomplish this kind of date formatting without going into a custom implementation. So, the short answer to this question is 'No'.
However, the problem still exists, so below is my own solution to the problem.
Make a subclass of NSDateFormatter and implement custom init and override stringFromDate:
method.
- (instancetype)initWithDateFormat:(NSString *)dateFormat
{
self = [super init];
if (self) {
NSLocale *locale = [NSLocale currentLocale];
self.locale = locale;
self.timeStyle = NSDateFormatterNoStyle;
self.dateStyle = NSDateFormatterShortStyle;
self.doesRelativeDateFormatting = YES;
self.dateFormat = dateFormat;
}
return self;
}
- (NSString *)stringFromDate:(NSDate *)date
{
NSString *dateFormat = self.dateFormat;
self.dateFormat = nil;
BOOL didRelativeDateFormatting = self.doesRelativeDateFormatting;
self.doesRelativeDateFormatting = YES;
NSString *result = [super stringFromDate:date];
if ([result rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].location != NSNotFound) {
self.dateFormat = dateFormat;
self.doesRelativeDateFormatting = NO;
result = [super stringFromDate:date];
}
self.dateFormat = dateFormat;
self.doesRelativeDateFormatting = didRelativeDateFormatting;
return result;
}
Since doesRelativeDateFormatting
and dateFormat
are mutually exclusive we try to use relative formatting first. Given that we set self.dateStyle = NSDateFormatterShortStyle
in the init method, we know the date will contain decimal numbers unless it is replaced with words meaning 'today', 'tomorrow' and anything that may appear in other languages. If we did not spot any numbers we accept this result.
If there are digital numbers in the string we assume the relative formatting did not happen, so we apply our own date format.