Objective c 限制每天行动一次

Objective c 限制每天行动一次,objective-c,ios,nsdate,ios5,Objective C,Ios,Nsdate,Ios5,在我的应用程序中,我希望允许用户每天只输入一次值 如何确保存储的NSDate不在当前日期内?我可以在忽略时间的情况下比较两个NSDate的日值吗?您可以将NSDate组件的实例与用户的日历一起使用,以查找工作日并将其与上次更新进行比较。比如说, NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *comps = [calendar components:NSWeekdayCalendarUnit fromD

在我的应用程序中,我希望允许用户每天只输入一次值


如何确保存储的NSDate不在当前日期内?我可以在忽略时间的情况下比较两个NSDate的日值吗?

您可以将NSDate组件的实例与用户的日历一起使用,以查找工作日并将其与上次更新进行比较。比如说,

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
NSInteger weekday = [comps weekday];
或者,您可以使用方法
components:fromDate:toDate:options:
检查两个日期之间的时间间隔天数,而不是日历中的当前日期。如果您希望每24小时而不是一周中的某一天给出一个答案,那么这可能会更有用


当然,如果这是针对在线游戏(或任何类似游戏),您希望验证服务器和客户端上的任何答案,那么用户很容易将日期或时区更改为“作弊”。

您可以使用NSDateComponents的实例以及用户的日历来查找工作日,并将其与上次更新进行比较。比如说,

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
NSInteger weekday = [comps weekday];
或者,您可以使用方法
components:fromDate:toDate:options:
检查两个日期之间的时间间隔天数,而不是日历中的当前日期。如果您希望每24小时而不是一周中的某一天给出一个答案,那么这可能会更有用


当然,如果这是针对在线游戏(或任何类似游戏),您希望验证服务器和客户端上的任何答案,那么用户很容易将日期或时区更改为“作弊”。

日期只是时间间隔的包装。他们没有当地时间的概念,所以你不能直接从他们那里得到一天的价值

您可以使用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])
{
    ...
}
//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
...
日期格式化程序使用您的本地时区输出日期,因此您可以保证用户的日期是正确的

如果你真的想确保活动间隔超过24小时(以防止作弊),那就简单多了,只要这样做:

if ([date1 timeIntervalSinceDate:date2] > 3600*24)
{
    ...
}
更新:正如abbood在评论中指出的,创建NSDateFormatter对象可能代价高昂/速度缓慢,因此如果要重用它们,您应该保留它们

将它们存储在静态变量或单例中不是一个好主意,因为它们不是线程安全的,但您可以将它们存储在当前线程的threadDictionary中,如下所示:

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])
{
    ...
}
//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
...

日期只是时间间隔的包装。他们没有当地时间的概念,所以你不能直接从他们那里得到一天的价值

您可以使用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])
{
    ...
}
//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
...
日期格式化程序使用您的本地时区输出日期,因此您可以保证用户的日期是正确的

如果你真的想确保活动间隔超过24小时(以防止作弊),那就简单多了,只要这样做:

if ([date1 timeIntervalSinceDate:date2] > 3600*24)
{
    ...
}
更新:正如abbood在评论中指出的,创建NSDateFormatter对象可能代价高昂/速度缓慢,因此如果要重用它们,您应该保留它们

将它们存储在静态变量或单例中不是一个好主意,因为它们不是线程安全的,但您可以将它们存储在当前线程的threadDictionary中,如下所示:

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])
{
    ...
}
//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
...

使用
NSWeekdayCalendarUnit
,如果用户在一周后的同一天尝试输入值,则会阻止他们这样做。我会使用
(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
。使用
NSWeekdayCalendarUnit
,如果用户在一周后的同一天尝试输入值,他们将无法这样做。我会使用
(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit)
。将格式化程序保存在Singleton或其他文件中是个好主意。。b/c,如果您要将上述代码归入某个类别或其他内容。。NSDateFormatter因其实例化时间而臭名昭著。将格式化程序保存在Singleton或其他东西中是个好主意。。b/c,如果您要将上述代码归入某个类别或其他内容。。NSDateFormatter因其实例化时间而臭名昭著