【问题标题】:How to check whether the date & time of a limit overlaps another limit or not?如何检查限制的日期和时间是否与另一个限制重叠?
【发布时间】:2013-07-27 18:58:41
【问题描述】:

我想检查日期限制*(例如:- 22/07/2013 2:30PM -22/07/2013 8:30PM )* 是否有另一个时间限制*(例如:- 22/07/2013 4:30PM -22/07/2013 6:30PM)* 与否。我对这个概念完全陌生。谁能告诉我如何做到这一点。

任何帮助将不胜感激

下面是我试过的代码:

- (void)viewDidLoad
{
    [self isDateInterval:@"8/1/2013 8:30am" and:@"8/1/2013 8:40am" fallsWithin:@"8/1/2013 8:30am" and:@"8/1/2013 8:55am"];
    [super viewDidLoad];
}

-(BOOL)isDateInterval:(NSString*)startDate1 and:(NSString*)endDate1 fallsWithin:(NSString*)startDate2 and:(NSString*)endDate2
{
    BOOL isWithinrange;

    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];

    [formatter setDateFormat:@"dd/MM/yyyy hh:mmaa"];

    NSTimeInterval ti1 = [[formatter dateFromString:startDate1] timeIntervalSince1970];
    NSTimeInterval ti2 = [[formatter dateFromString:endDate1] timeIntervalSince1970];

    NSTimeInterval ti3 = [[formatter dateFromString:startDate2] timeIntervalSince1970];
    NSTimeInterval ti4 = [[formatter dateFromString:endDate2] timeIntervalSince1970];

    if( (ti3 > ti1 && ti3 < ti2) || (ti3 < ti1 && ti4 > ti1) )
    {
        //Date with in range
        isWithinrange=TRUE;
    }
    else
    {
        isWithinrange=FALSE;
        //Not with in range
    }

    return isWithinrange;
}

我希望输出为“isWithin”,因为一个时间间隔的一部分正在进入另一个时间间隔

【问题讨论】:

  • 日期是如何存储的?成对?你可以使用谓词。
  • @Wain 日期将存储到 SQLite 中。格式如 MM/DD/YYYY Time:aa
  • 您想知道第一个时间间隔是否完全包含在第二个时间间隔中,或者它们是否在某处重叠?对于您的示例日期,第二个时间间隔完全包含在第一个时间间隔内。因此,它们重叠。但是 22/07/2013 2:30PM - 22/07/2013 5:30PM 与您的第二个间隔重叠,但不包含它。您要计算哪个?
  • 如果你想检查“重叠时间间隔”,那么你应该重命名你的问题
  • 看看它可能会有所帮助:github.com/Chintan-Dave/CRDValidation

标签: iphone ios objective-c nsdate


【解决方案1】:

此代码将为您提供所需的内容。它检查两个间隔的开始日期或结束日期是否在另一个间隔的开始日期和结束日期之间。

- (BOOL)timeIntervalFromDate:(NSString *)dateString toDate:(NSString *)anotherDateString overlapsWithTimeIntervalFromDate:(NSString *)date2String toDate:(NSString *)anotherDate2String {
    BOOL isWithinRange = NO;

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"dd/MM/yyyy hh:mmaa";

    NSDate *date = [formatter dateFromString:dateString];
    NSDate *anotherDate = [formatter dateFromString:anotherDateString];
    NSDate *date2 = [formatter dateFromString:date2String];
    NSDate *anotherDate2 = [formatter dateFromString:anotherDate2String];

    NSDate *startDate = [date earlierDate:anotherDate];
    NSDate *endDate = [date laterDate:anotherDate];

    NSDate *otherStartDate = [date2 earlierDate:anotherDate2];
    NSDate *otherEndDate = [date2 laterDate:anotherDate2];

    BOOL startDateIsEarlierThanOtherStartDate = [startDate earlierDate:otherStartDate] == startDate;
    BOOL endDateIsLaterThanOtherStartDate = [endDate laterDate:otherStartDate] == endDate;

    BOOL startDateIsEarlierThanOtherEndDate = [startDate earlierDate:otherEndDate] == startDate;
    BOOL endDateIsLaterThanOtherEndDate = [endDate laterDate:otherEndDate] == endDate;

    BOOL otherStartDateIsEarlierThanStartDate = [startDate earlierDate:otherStartDate] == otherStartDate;
    BOOL otherEndDateIsLaterThanStartDate = [otherEndDate laterDate:startDate] == otherEndDate;

    BOOL otherEndDateIsEarlierThanStartDate = [startDate earlierDate:otherEndDate] == otherEndDate;
    BOOL otherEndDateIsLaterThanEndDate = [endDate laterDate:otherEndDate] == otherEndDate;

    isWithinRange = (startDateIsEarlierThanOtherStartDate && endDateIsLaterThanOtherStartDate) || (startDateIsEarlierThanOtherEndDate && endDateIsLaterThanOtherEndDate) || (otherStartDateIsEarlierThanStartDate && otherEndDateIsLaterThanStartDate) || (otherEndDateIsEarlierThanStartDate && otherEndDateIsLaterThanEndDate);

    return isWithinRange;
}

为了说明每种可能的情况,任何一对布尔语句都必须为真。向方法提供日期对的顺序无关紧要。

【讨论】:

  • 顺便说一句,我建议在此方法之外使用NSDateFormatter 代码,而让此方法直接接受NSDate 对象。这是一种更好的编码风格,只抽象不会重复的内容。
  • 这可以更简单地表达far。您只需要查找哪个开始日期更早;那么,如果相应的结束日期在较晚的开始日期之后,则存在重叠。这是三个比较而不是八个。 (见my answer。)
【解决方案2】:
-(BOOL)isDateInterval:(NSString*)startDate1 and:(NSString*)endDate1 fallsWithin:(NSString*)startDate2 and:(NSString*)endDate2
{
    BOOL isWithinrange;

    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];

    [formatter setDateFormat:@"dd/MM/yyyy hh:mmaa"];

    NSTimeInterval ti1 = [[formatter dateFromString:startDate2] timeIntervalSince1970];
    NSTimeInterval ti2 = [[formatter dateFromString:endDate2] timeIntervalSince1970];

    NSTimeInterval ti3 = [[formatter dateFromString:startDate1] timeIntervalSince1970];
    NSTimeInterval ti4 = [[formatter dateFromString:endDate1] timeIntervalSince1970];

    if( (ti3 > ti1 && ti3 < ti2) || (ti3 < ti1 && ti4 > ti1) )
    {
        //Date with in range
        isWithinrange=TRUE;
    }
    else
    {
        isWithinrange=FALSE;
        //Not with in range
    }

    return isWithinrange;
}

【讨论】:

  • @Apurv 它仅在一种情况下有效,但在以下情况下始终显示“不在范围内”。案例 1:Strt Time 8/07/2013 2:00am endTime 8/07/2013 4:00am 另一个间隔 Strt Time 8/07/2013 2:30am endTime 8/07/2013 4:30am。案例 2:Strt Time 8/07/2013 2:30am endTime 8/07/2013 4:30am 另一个时间间隔 Strt Time 8/07/2013 2:00am endTime 8/07/2013 4:00am。
  • @Apurv 只要选定的时间间隔落在另一个时间间隔内,它就应该说“在范围内”
  • @surendher 查看更新后的答案。它应该检查适当的范围
  • @surendher:您需要在计算时间间隔时更改开始日期和结束日期。请查看更新后的答案。
  • 我仍然得到输出“不在范围内”。如果一个时间间隔的一部分落在该间隔的另一部分内,它应该说“在范围内”。
【解决方案3】:

我们有四个日期,firstStartDatefirstEndDatesecondStartDatesecondEndDate。假设这两个开始日期实际上总是早于它们对应的结束日期,有六种排序方式:

+ start1 start2 end2 end1
+ start1 start2 end1 end2
x start1 end1 start2 end2
+ start2 start1 end2 end1
+ start2 start1 end1 end2
x start2 end2 start1 end1

其中四个排序——我用+ 标记的那些——构成给定时间段的重叠。重叠有一个共同点:无论哪个开始日期早于另一个,匹配的结束日期必须在第二个开始之后。这很容易放入代码中:

@implementation NSDate (WSSComparisons)

- (BOOL)WSSIsLaterThanDate:(NSDate *)date
{
    return (self == [self laterDate:date]);
}

- (BOOL)WSSIsEarlierThanDate:(NSDate *)date
{
    return (self == [self earlierDate:date]);
}

@end

- (BOOL)periodFromDate:(NSDate *)firstStartDate toDate:(NSDate *)firstEndDate 
overlapsPeriodFromDate:(NSDate *)secondStartDate toDate:(NSDate *)secondEndDate
{
    /*
    // Sanity check?
    if( [firstStartDate WSSIsLaterThanDate:firstEndDate] || 
        [secondStartDate WSSIsLaterThanDate:secondEndDate] ){

        return NO;
    }
    */

    // If firstStartDate is before secondStartDate and firstEndDate isn't,
    // they overlap
    if( [firstStartDate WSSIsEarlierThanDate:secondStartDate] ){
        return [firstEndDate WSSIsLaterThanDate:secondStartDate];
    }
    else {
        // Likewise for secondStartDate
        return [secondEndDate WSSIsLaterThanDate:firstStartDate];
    }
}

如果你的“日期”恰好是字符串,逻辑是一样的;只需添加 NSDateFormatter with the appropriate format 并解析即可。

【讨论】:

    【解决方案4】:

    看看来自 Apple 的 NSDate documentation

    看方法:

    isEqualToDate:earlierDate:laterDate:compare:

    这些是您需要检查日期是否在一个范围内的方法。您需要先将日期文本转换为 NSDate。见NSDateFormatterclass reference

    希望这能让你走上正确的道路。

    【讨论】:

      猜你喜欢
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      相关资源
      最近更新 更多