2012-10-27 55 views
4

可能重复:
Determine if current local time is between two times (ignoring the date portion)如何检查当前时间是否在ios的指定范围内?

在iOS中,我怎么能做到以下几点:

我有两个NSDate对象代表一个店的开闭时间。这些对象中的时间是准确的,但日期未指定(商店在同一时间打开和关闭,而不考虑日期)。我如何检查当前时间是否在这个时间范围内?

请注意,如果它可以帮助打开和关闭时间使用除NSDate之外的其他格式,那么我很好。目前,我只是从文件中读取日期字符串,如“12:30”,并使用日期格式化程序创建匹配的NSDate对象。

+1

我错过了什么,或者你真的只是在寻找' - [NSDate比较:]'? – 2012-10-27 16:48:56

+0

问题是,首先不会比较日期和时间,而不仅仅是时间?如上所述,这些打开和关闭时间对象的时间字段只是初始化的。日,月,年字段不是。 – Nosrettap

+0

在这种情况下,您可以使用[NSDateComponents类。](https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDateComponents_Class/Reference/Reference.html) – 2012-10-27 16:56:12

回答

15

更新:请注意,此解决方案特定于您的情况,并假定商店开放时间不会跨越两天。例如,如果开放时间从星期一晚上9点到星期二上午10点,它将不起作用。自晚上10点晚上9点以后,但不是上午10点以前(一天内)。所以记住这一点。

我制作了一个函数,它会告诉你一个日期的时间是否在两个其他日期之间(忽略年,月和日)。还有第二个辅助函数,它为您提供了一个新的NSDate,其年,月和日组件被“中和”(例如设置为某个静态值)。

这个想法是将年份,月份和日期组件设置为在所有日期之间相同,以便比较仅依赖于时间。

我不确定它是否是最有效的方法,但它的工作原理。

- (NSDate *)dateByNeutralizingDateComponentsOfDate:(NSDate *)originalDate { 
    NSCalendar *gregorian = [[[NSCalendar alloc] 
           initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; 

    // Get the components for this date 
    NSDateComponents *components = [gregorian components: (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate: originalDate]; 

    // Set the year, month and day to some values (the values are arbitrary) 
    [components setYear:2000]; 
    [components setMonth:1]; 
    [components setDay:1]; 

    return [gregorian dateFromComponents:components]; 
} 

- (BOOL)isTimeOfDate:(NSDate *)targetDate betweenStartDate:(NSDate *)startDate andEndDate:(NSDate *)endDate { 
    if (!targetDate || !startDate || !endDate) { 
     return NO; 
    } 

    // Make sure all the dates have the same date component. 
    NSDate *newStartDate = [self dateByNeutralizingDateComponentsOfDate:startDate]; 
    NSDate *newEndDate = [self dateByNeutralizingDateComponentsOfDate:endDate]; 
    NSDate *newTargetDate = [self dateByNeutralizingDateComponentsOfDate:targetDate]; 

    // Compare the target with the start and end dates 
    NSComparisonResult compareTargetToStart = [newTargetDate compare:newStartDate]; 
    NSComparisonResult compareTargetToEnd = [newTargetDate compare:newEndDate]; 

    return (compareTargetToStart == NSOrderedDescending && compareTargetToEnd == NSOrderedAscending); 
} 

我用这段代码来测试它。您可以看到年,月和日被设置为一些随机值,并且不会影响时间检查。

NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease]; 
[dateFormatter setDateFormat:@"yyyy:MM:dd HH:mm:ss"]; 

NSDate *openingDate = [dateFormatter dateFromString:@"2012:03:12 12:30:12"]; 
NSDate *closingDate = [dateFormatter dateFromString:@"1983:11:01 17:12:00"]; 
NSDate *targetDate = [dateFormatter dateFromString:@"2034:09:24 14:15:54"]; 

if ([self isTimeOfDate:targetDate betweenStartDate:openingDate andEndDate:closingDate]) { 
    NSLog(@"TARGET IS INSIDE!"); 
}else { 
    NSLog(@"TARGET IS NOT INSIDE!"); 
} 
+0

谢谢,这节省了我很多时间。我把所有东西放在一个很好的类别中 – palme

+0

@nebs在我的案件开放时间跨度两天。如何处理它? –

+0

@EvgenyKarkan我还没有尝试过,但你可以更新中和函数来设置相对日期偏移量。因此,例如,将所有比较日期的日期设置为“1”,而不是将未来的日期设置为“2”。然后在理论上其余的应该按原样工作。 – nebs

相关问题