Сравнить NSDate для Сегодня или Вчера
Ну, я думаю, это было задано тысячу раз, но почему-то ответы не работают или не имеют других проблем,...
В любом случае, вот что я "работаю":
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *currentDate = [NSDate date];
NSDateComponents *comps = [[NSDateComponents alloc] init];
// set tomorrow (0: today, -1: yesterday)
[comps setDay:0];
NSDate *dateToday = [calendar dateByAddingComponents:comps toDate:currentDate options:0];
[comps setDay:-1];
NSDate *dateYesterday = [calendar dateByAddingComponents:comps toDate:currentDate options:0];
[comps release];
NSString *todayString = [self.dateFormatter stringFromDate:dateToday] ;
NSString *yesterdayString = [self.dateFormatter stringFromDate:dateYesterday] ;
NSString *refDateString = [self.dateFormatter stringFromDate:info.date];
if ([refDateString isEqualToString:todayString])
{
cell.title.text = @"Today";
} else if ([refDateString isEqualToString:yesterdayString])
{
cell.title.text = @"Yesterday";
} else
{
cell.title.text = [self.dateFormatter stringFromDate:info.date];
}
Теперь к проблеме (задачам):
Это, кажется, очень много кода для сравнения только даты, есть ли более простой способ?
И самый важный вопрос - это выпуск всех объектов. Как я мог предположить, я использую это в UITableViewController. У меня также есть эти строки в моем коде:
//[calendar release];
//[currentDate release];
//[dateToday release];
//[dateYesterday release];
//[todayString release];
//[yesterdayString release];
//[refDateString release];
Проблема в том, что как только я раскомментирую одну из этих строк, мое приложение падает, и я понятия не имею, почему?! Надеюсь, кто-то может просветить меня здесь.
Спасибо большое.
Ответы
Ответ 1
Самый простой способ сделать это - просто сравнить description
дат:
// Your dates:
NSDate * today = [NSDate date];
NSDate * yesterday = [NSDate dateWithTimeIntervalSinceNow:-86400]; //86400 is the seconds in a day
NSDate * refDate; // your reference date
// 10 first characters of description is the calendar date:
NSString * todayString = [[today description] substringToIndex:10];
NSString * yesterdayString = [[yesterday description] substringToIndex:10];
NSString * refDateString = [[refDate description] substringToIndex:10];
if ([refDateString isEqualToString:todayString])
{
cell.title.text = @"Today";
} else if ([refDateString isEqualToString:yesterdayString])
{
cell.title.text = @"Yesterday";
} else
{
cell.title.text = refDateString;
}
Если вы хотите изменить формат строки даты, вы можете использовать descriptionWithLocale:
вместо этого.
Ответ 2
Я знаю, что это старый вопрос, но я просто делал что-то подобное себе и натолкнулся на него.
Прежде всего, поскольку iOS 4.0 (и Mac OS 10.6), NSDateFormatter
может выполнять относительные даты, что дает вам "Сегодня" и "Вчера" автоматически.
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
[formatter setTimeStyle:NSDateFormatterNoStyle];
[formatter setDateStyle:NSDateFormatterShortStyle];
[formatter setDoesRelativeDateFormatting:YES];
NSString* dateString = [formatter stringFromDate:[NSDate date]];
NSLog( @"date = %@", dateString );
Какие выходы:
2014-03-15 15:26:37.683 TestApp[1293:303] date = Today
Тем не менее, OP спрашивал, как сравнить NSDate
сегодня или вчера, то, что я также хотел сделать, относительное форматирование даты в сторону. Вот что я придумал, реализованный как категория на NSDate
:
@implementation NSDate (IsToday)
- (BOOL) isToday
{
NSCalendar* calendar = [NSCalendar currentCalendar];
// Components representing the day of our date.
NSDateComponents* dateComp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:self];
NSDate* date = [calendar dateFromComponents:dateComp];
// Components representing today.
NSDateComponents* todayComp = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:[NSDate date]];
NSDate* todayDate = [calendar dateFromComponents:todayComp];
// If the dates are equal, then our date is today.
return [date isEqualToDate:todayDate];
}
@end
Причина, по которой я хотел сделать это, - это показать время, созданное сегодня, и дату вещей, которые не созданы сегодня - подобно тому, как Mail.app показывает даты в сообщениях. Это выглядит так:
- (NSString*) postDateToString:(NSDate*)aDate
{
static NSDateFormatter* todayFormatter = nil;
if( todayFormatter == nil ) {
todayFormatter = [[NSDateFormatter alloc] init];
[todayFormatter setTimeStyle:NSDateFormatterShortStyle];
[todayFormatter setDateStyle:NSDateFormatterNoStyle];
}
static NSDateFormatter* notTodayFormatter = nil;
if( notTodayFormatter == nil ) {
notTodayFormatter = [[NSDateFormatter alloc] init];
[notTodayFormatter setTimeStyle:NSDateFormatterNoStyle];
[notTodayFormatter setDateStyle:NSDateFormatterShortStyle];
[notTodayFormatter setDoesRelativeDateFormatting:YES];
}
NSDateFormatter* formatter = notTodayFormatter;
if( [aDate isToday] ) {
formatter = todayFormatter;
}
return [formatter stringFromDate:aDate];
}
Ответ 3
Я могу предложить использовать этот проект с открытым исходным кодом:
https://github.com/erica/NSDate-Extensions
Вы можете проверить текущие методы:
+ (NSDate *) dateTomorrow
+ (NSDate *) dateYesterday
Ответ 4
Вы можете сравнить два объекта NSDate с помощью метода isEqualToDate, вернет bool (да или нет), сообщив вам, совпадают ли даты. См. Документация Apple.
Что касается освобождения объектов - правило в objective-c заключается в том, что вы только освобождаете объекты, которые вы выделяете для памяти во время вашего метода. Единственный объект, который вы специально выделяете для памяти в своем коде, - это comps, поэтому он единственный, который вы должны выпустить - и вы это сделали. Освобождение памяти для объектов, которые вы никогда не выделяли, вероятно, приводит к сбою вашего приложения. Когда методы, которые фактически выделяют эти объекты, пытаются их освободить или другая ссылка на них пытается получить к ним доступ, они вызовут ошибку EXC_BAD_ACCESS, как вы уже их выпустили!
Поэтому не просто комментируйте эти строки выпуска, удаляйте их из своего script - им не нужно!