【问题标题】:How to find if an NSDate is within a specified range?如何查找 NSDate 是否在指定范围内?
【发布时间】:2011-04-07 01:16:26
【问题描述】:

所以,我很难找到 NSDate 是否在特定范围内(不是双关语)。考虑一下:下午 5:00 到 6:00 之间的预定访问。我想知道预定的访问是否在当前时间的 +/- 15 分钟内。因此,我的 safe 范围是下午 4:45 到下午 6:15。我怎样才能知道预定的访问是在范围内还是不在范围内?这是我到目前为止得到的代码,它根本不起作用......

- (BOOL)isInScheduledRange {
//    NSLog(@"Start: %f", [self.start timeIntervalSinceNow]);
//    NSLog(@"End: %f", [self.end timeIntervalSinceNow]);
//    
//    if (([self.start timeIntervalSinceNow] >= -900) && ([self.end timeIntervalSinceNow] <= 3600)) {
//        NSLog(@"In Range");
//        
//        return YES;
//    }
//    
    NSDate *now = [[NSDate alloc] init];

//    if ((([self.start timeIntervalSinceDate:now] >= -900) && ([self.start timeIntervalSinceDate:now] <= 900)) && (([self.end timeIntervalSinceDate:now] <= -900) && ([self.end timeIntervalSinceDate:now] >= 900))) {
//        NSLog(@"In Range");
//    }

    NSLog(@"%@; %@; %@", now, self.start, self.end);
//    NSLog(@"%@; %@", [self.start timeIntervalSinceDate:now], [self.end timeIntervalSinceDate:now]);

    if ((([self.start timeIntervalSinceDate:now] >= -900) && ([self.start timeIntervalSinceDate:now] <= 0)) && (([self.end timeIntervalSinceDate:now] >= 0) && ([self.end timeIntervalSinceDate:now] <= 900))) {
        NSLog(@"In Range");
    }

    return NO;

    [now release];
}

我会很感激一些帮助。我在计算这个时间时遇到了困难。

另外,我讨厌与时间打交道,无论我使用什么平台...

【问题讨论】:

    标签: objective-c ios nsdate


    【解决方案1】:

    您要检查开始时间是否小于当前时间之后 900 秒,以及结束时间是否小于当前时间之前 900 秒。 timeIntervalSinceDate: 如果调用它的对象在参数之后,则返回一个正数,您需要检查 start = -900。此外,您可以使用timeIntervalSinceNow 来简化代码,而不是手动获取当前日期并将其传递给timeIntervalSinceDate:。最后,如果您可以假设(或之前确保)开始在结束之前,那么您不需要两个中间测试,因为它们都必须为真,其他两个都为真。

    if([self.start timeIntervalSinceNow] <= 900 && [self.end timeIntervalSinceNow] >= −900) {
        NSLog(@"In range")
    }
    

    【讨论】:

    • 这个答案比我的好。
    • 这行得通,看来我第一次注释掉的尝试是最接近的。感谢您的帮助!
    【解决方案2】:

    这里有一些冗长(和愚蠢)的代码来解释我解决这个问题的方法

    NSTimeInterval secondsBeforeStart = [self.start timeIntervalSinceNow];
    if ( secondsBeforeStart > (15 * 60))
    {
        // The result for '[self.start timeIntervalSinceNow]' is positive as long
        //  as 'self.start' remains in the future. We're not in range until there
        //  are 900 seconds to go or less.
        NSLog( @"Still time to chill.");
    
        // More than fifteen minutes to go so return NO.
        return NO;
    }
    else
    {
        NSLog( @"OMG did I miss it!!!");
        NSTimeInterval secondsBeforeEnd = [self.end timeIntervalSinceNow];
        if ( secondsBeforeEnd < -( 15 * 60))
        {
            // The result for '[self.end timeIntervalSinceNow]' is negative when
            //  'self.end' is in the past. 
            // It's been more than 900 seconds since the end of the appointment
            //  so we've missed it.
            NSLog( @"Ahhhhh!!!");
    
            // More than 900 seconds past the end of the event so return NO.
            return NO;
        }
        else
        {
            // We are somewhere between 900 seconds before the start and
            //  900 seconds before the end so we are golden.
            NSLog( @"Whew, we made it.");
            return YES;
        }
    }
    

    我的编码方式应该是

    BOOL inRange = NO;  // Assume we are not in the proper time range.
    
    if ( [self.start timeIntervalSinceNow] <= ( 15 * 60))
    {
        // 'Now' is at least 900 seconds before the start time but could be later.
        if ( [self.end timeIntervalSinceNow] >= -( 15 * 60))
        {
            // 'Now' is not yet 900 seconds past the end time.
            inRange = YES
        }
    }
    
    return inRange;
    

    注意:我实际上并没有编译这个,但我很确定逻辑是正确的。

    最后,您确实注意到了最后两行

        return NO;
    
        [now release];
    }
    

    会造成内存泄漏。 (释放然后返回;^))

    【讨论】:

    • 这是你和@ughoavgfhw 之间的艰难选择,因为你们俩本质上说的是同一件事,但最后@ughoavgfhw 的代码与我写的几乎相同,所以我和他一起去了。 但是,我非常感谢您的 lol 帖子和有关泄漏的提示。
    【解决方案3】:

    这是一个距离问题 - 您想知道当前时间是否在目标时间的 900 秒内。通过取两点之差的绝对值来计算距离问题。通过取差值的绝对值,两个样本的顺序无关紧要。

    /** 
     * @brief Return YES if the current time is within 900 seconds of the meeting time (NSDate* time).
     */
    -(BOOL)currentTimeIsWithin900SecondsOf:(NSDate*)time
    {
        NSDate* now = [NSDate date];
        return fabs( [now timeIntervalSinceReferenceDate] - [time timeIntervalSinceReferenceDate] ) < 900;
    }
    

    【讨论】:

      【解决方案4】:

      您需要创建三个 NSDate。然后使用 intervalSinceReferenceDate 将 NSDates 转换为时间间隔并进行比较。您可以使用 NSDateComponents 手动设置 NSDates。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-01
        • 2021-03-15
        • 1970-01-01
        相关资源
        最近更新 更多