Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Ограничьте действие до одного раза в день

Автор вопроса: AyradОтветов: 2

В моем приложении я хотел бы разрешить пользователю вводить значение только один раз в день.

Как убедиться, что сохраненная NSDate не относится к текущему дню? Могу ли я сравнить дневное значение двух NSDate, игнорируя время?

iosobjective-cnsdateios5

Ответы

Ответ 1 · рейтинг 2 · Nick Lockwood

Даты - это просто обертки вокруг NSTimeIntervals. У них нет понятия местного времени, поэтому вы не можете напрямую получить от них значение дня.

Вы можете использовать NSDateFormatter, например:

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy/MM/dd"];

NSString *today = [formatter stringFromDate:[NSDate date]];

NSString *dateToCompare = [formatter stringFromDate:someDate];

if ([dateToCompare isEqualToString:today])
{
    ...
}

Средства форматирования даты выводят дату с использованием вашего местного часового пояса, поэтому вы можете гарантировать, что день будет правильным для пользователя.

Если вы действительно хотите, чтобы события происходили с интервалом более 24 часов (чтобы предотвратить мошенничество), это намного проще, просто сделайте следующее:

if ([date1 timeIntervalSinceDate:date2] > 3600*24)
{
    ...
}

ОБНОВЛЕНИЕ: Как указано abbood в комментариях, создание объектов NSDateFormatter может быть дорогим/медленным, поэтому вам следует придерживаться их, если они будут использоваться повторно.

Не рекомендуется хранить их в статической переменной или синглтоне, потому что они не являются потокобезопасными, но вы можете сохранить их в threadDictionary текущего потока, например так:

//check for a cached formatter and recreate if needed
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
NSDateFormatter *formatter = threadDict[@"someUniqueKey"];
if (!formatter)
{
    //create the formatter
    formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy/MM/dd"];

    //cache the formatter
    threadDict[@"someUniqueKey"] = formatter;
}

//use the formatter
...

Ответ 2 · рейтинг 1 · Marc Charbonneau

Вы можете использовать экземпляр NSDateComponents вместе с календарем пользователя, чтобы найти день недели и сравнить его с последним обновлением. Например,

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
NSInteger weekday = [comps weekday];

В качестве альтернативы вы можете использовать метод components:fromDate:toDate:options: для проверки количества дней в интервале времени между двумя датами вместо текущего дня в календаре. Это может быть более полезно, если вы хотите разрешить ответ каждые 24 часа, а не день недели.

Конечно, если это для онлайн-игры (или чего-то подобного), вы хотите проверить любые ответы на сервере, а также на клиенте, пользователю легко изменить дату или часовой пояс на "обмануть".

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы