iOS: сравнение дат не выполняется в реальных условиях, работает в смоделированных условиях

Я использую этот код для сравнения двух дат, чтобы увидеть, является ли сохраненная дата по существу вчерашней:

NSDate *date = [wordData objectForKey:@"date"];
NSLog(@"Word data date: %@", [wordData objectForKey:@"date"]);

NSDate *nowDate = [NSDate date];
NSLog(@"Date now: %@", nowDate);

NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *date1Components = [cal components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
NSDateComponents *date2Components = [cal components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:nowDate];
NSComparisonResult comparison = [[cal dateFromComponents:date1Components] compare:[cal dateFromComponents:date2Components]];


if(comparison == NSOrderedAscending)
{
    NSLog(@"Word out of date, fetching new date");
    [self fetchCurrentWord];
}
if(comparison == NSOrderedDescending)
{
    NSLog(@"Word is newer");
}
else if(comparison == NSOrderedSame)
{
    NSLog(@"Same date");
}

Однако, когда дата меняется на устройстве, как правило, код возвращается NSOrderedSame, если я имитирую это путем изменения времени устройства вручную, оно работает, или если я использую dateWithTimeIntervalSinceNow оно работает. Я добавил отладочные отпечатки, и даты выглядят хорошо, они изначально созданы с использованием NSDate, поэтому не должно быть различий в формате. Я рисую пробел на том, что это может быть на самом деле.

Журнал отказов:

Oct 17 11:25:05 Nicholas-Smiths-iPhone WOTD[2493] <Warning>: Word is: CLIMATURE, A climate. [Obs.] Shak., 2014-10-16 23:05:16 +0000
Oct 17 11:25:05 Nicholas-Smiths-iPhone WOTD[2493] <Warning>: Word CLIMATURE, definition A climate. [Obs.] Shak.
Oct 17 11:25:05 Nicholas-Smiths-iPhone WOTD[2493] <Warning>: Word date: 2014-10-16 23:05:16 +0000
Oct 17 11:25:05 Nicholas-Smiths-iPhone WOTD[2493] <Warning>: Word data date: 2014-10-16 23:05:16 +0000
Oct 17 11:25:05 Nicholas-Smiths-iPhone WOTD[2493] <Warning>: Date now: 2014-10-17 10:25:05 +0000
Oct 17 11:25:05 Nicholas-Smiths-iPhone WOTD[2493] <Warning>: Same date

Журнал успеха:

2014-10-15 16:35:37.748 WOTD[960:31212] Word is: CONTORTUPLICATE, Plaited lengthwise and twisted in addition, as the bud of themorning-glory. Gray., 2014-10-15 14:43:04 +0000
2014-10-15 16:35:37.749 WOTD[960:31212] Word CONTORTUPLICATE, definition Plaited lengthwise and twisted in addition, as the bud of themorning-glory. Gray.
2014-10-15 16:35:37.749 WOTD[960:31212] Word date: 2014-10-15 14:43:04 +0000
2014-10-15 16:35:37.749 WOTD[960:31212] Word data date: 2014-10-15 14:43:04 +0000
2014-10-15 16:35:37.749 WOTD[960:31212] Date now: 2014-10-15 15:35:37 +0000
2014-10-15 16:35:37.750 WOTD[960:31212] Same date

Я изменил время вручную на этом этапе

2014-10-16 16:37:29.286 WOTD[1133:38254] Word is: CONTORTUPLICATE, Plaited lengthwise and twisted in addition, as the bud of themorning-glory. Gray., 2014-10-15 14:43:04 +0000
2014-10-16 16:37:29.287 WOTD[1133:38254] Word CONTORTUPLICATE, definition Plaited lengthwise and twisted in addition, as the bud of themorning-glory. Gray.
2014-10-16 16:37:29.287 WOTD[1133:38254] Word date: 2014-10-15 14:43:04 +0000
2014-10-16 16:37:29.287 WOTD[1133:38254] Word data date: 2014-10-15 14:43:04 +0000
2014-10-16 16:37:29.287 WOTD[1133:38254] Date now: 2014-10-16 15:37:29 +0000
2014-10-16 16:37:29.288 WOTD[1133:38254] Word out of date, fetching new date
2014-10-16 16:37:29.616 WOTD[1133:38538] Word PAC, definition A kind of moccasin, having the edges of the sole turned up andsewed to the upper. Knight.

1 ответ

Решение

Пример, который вы показываете как неудачный на самом деле, в тот же день - это сравнение с UTC по сравнению с BST - слово date находится в тот же день, что и 23:05 + 1 час = 00:05 = сегодня.

Вам нужно позаботиться о работе с датами из-за часовых поясов, если вы хотите знать, произошло ли что-то вчера, по сравнению с сегодняшним днем, лучшим подходом может быть:

NSDate *startOfDay;
NSTimeInterval lengthOfDayInSeconds;
BOOL success = [cal rangeOfUnit:NSCalendarUnitDay startDate:&startOfDay interval:&lengthOfDayInSeconds forDate:[NSDate date]];

Это дает вам дату для начала сегодня startOfDay (соответствует часовому поясу местного календаря), который затем можно сравнить с датой теста с помощью простого сравнения.

Другие вопросы по тегам