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

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

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


person Ayrad    schedule 03.02.2012    source источник


Ответы (2)


arrow_upward
2
arrow_downward

Даты — это просто обертки вокруг 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
...
person Nick Lockwood    schedule 03.02.2012
comment
вероятно, было бы неплохо сохранить средство форматирования в синглтоне или что-то в этом роде.. b/c, если вы собираетесь поместить приведенный выше код в категорию или что-то в этом роде.. nsdateformatters печально известны своим временем создания экземпляров. - person abbood; 28.04.2014

arrow_upward
1
arrow_downward

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

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

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

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

person Marc Charbonneau    schedule 03.02.2012
comment
С NSWeekdayCalendarUnit, если пользователь попытается ввести значение в тот же день через неделю, он не сможет это сделать. Вместо этого я бы использовал (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit). - person yuji; 06.02.2012