【问题标题】:Date comparison between two NSDate两个 NSDate 之间的日期比较
【发布时间】:2012-05-30 19:08:00
【问题描述】:

这是我第一次在 Objective-C 中比较日期。我已经在网上搜索了一段时间,我发现的所有示例都涉及从字符串构建 NSDate,所以我决定在这里提出一个新问题...... 我的问题如下:

我需要知道两个 NSDate 是否在同一天,忽略时间。我有两个 NSArray 包含一组日期,我需要一个一个地确定第一个 NSArray 中的哪一个与第二个数组在同一天。

- (void)setActiveDaysColor:(UIColor *)activeDaysColor
{
    for (DayView *actualDay in _days)
    {
        NSDate *actualDayDate = [actualDay date];

        for (NSDate *activeDayDate in self.dates)
        {
            // Comparison code
            // If both dates are the same, tint actualDay with a different color
        }
    }
}

提前感谢您,祝您有美好的一天。

亚历克斯。

【问题讨论】:

    标签: objective-c ios date nsdate


    【解决方案1】:

    通过省略时间组件来创建新日期。并使用其中一种比较方法

    例子

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSInteger components = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);
    
    NSDateComponents *firstComponents = [calendar components:components fromDate:firstDate];
    NSDateComponents *secondComponents = [calendar components:components fromDate:secondDate];
    
    NSDate *date1 = [calendar dateFromComponents:firstComponents];
    NSDate *date2 = [calendar dateFromComponents:secondComponents];
    
    NSComparisonResult result = [date1 compare:date2];
    if (result == NSOrderedAscending) {
    } else if (result == NSOrderedDescending) {
    }  else {
    }
    

    【讨论】:

    【解决方案2】:
    -(BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 {
    NSCalendar* calendar = [NSCalendar currentCalendar];
    
    unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit;
    NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
    NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];
    
    return [comp1 day]   == [comp2 day] &&
    [comp1 month] == [comp2 month] &&
    [comp1 year]  == [comp2 year];}
    

    【讨论】:

      【解决方案3】:

      查看 NSDate 文档,这些是比较日期的方法

      • isEqualToDate
      • 较早日期
      • 稍后日期
      • 比较

      在你的情况下

      if([actualDayDate isEqualToDate:activeDayDate])
      {
      
      }
      

      【讨论】:

      • 不,这只会检查它们是否是完全相同的时刻,而不是同一天。
      • 啊,我的错。谢谢。我错过了。
      【解决方案4】:

      感谢您的所有回答。 我在一篇完全不相关的帖子中找到了对我的问题的更清晰的答案,但实际上效果很好。

      if ((unsigned int)[actualDayDate timeIntervalSinceDate:activeDayDate] / 60 / 60 / 24 == 0)
      {
           // do Stuff
      }
      

      【讨论】:

      • 请注意,如果用户使用其他日历而不是公历,则此代码可能会失败。日期的比较必须在日历内完成。 stackoverflow.com/questions/6184824/…
      • 你最好使用我的解决方案。如果您觉得代码行数太多,请在其 NSDate 上创建一个类别,方法为 compareDateOmmitingTime:
      【解决方案5】:

      您可以使用谓词来过滤掉当前存在的所有对象,而不是代码中的循环。通过将其与今天的开始和今天的结束进行比较来过滤出今天的日期。

      您可以像这样将任何 NSDate 设置为该日期的开头(请参阅this answer

      NSDate *beginDate = [NSDate date];
      [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&beginDate interval:NULL forDate:beginDate];
      

      然后,您只需添加一天即可获得结束日期。 不要通过计算秒数来添加天数。这不适用于夏令时!这样做(另见this answer):

      NSDateComponents *oneDay = [[NSDateComponents alloc] init];
      [oneDay setDay:1];
      // one day after begin date
      NSDate *endDate = [[NSCalendar currentCalendar] dateByAddingComponents:oneDay toDate:beginDate options:0];
      

      现在您有了定义今天范围的两个日期,您可以使用 NSPredicate 过滤所有 DayView,以获取今天是今天的所有 DayView 的新数组,如下所示(参见 this answer):

      // filter DayViews to only include those where the day is today
      NSArray *daysThatAreToday = [_days filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", beginDate, endDate]];
      

      现在您可以通过枚举新数组(包含今天的 DayViews)将色调颜色应用于所有 DayViews

      [daysThatAreToday enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
          // Set the tint color here...
      }];
      

      在我看来,这是一种干净的但更重要的是正确解决问题的方法。它可以清楚地阅读并处理夏令时和其他日历,然后是公历。如果您想为某一周(或任何其他时间段)的所有 DayView 着色,也可以轻松地重复使用它。

      【讨论】:

      • 请注意,使用此代码,您将完全删除时间组件。如果你仍然需要它,你应该做NSDate *newStartDateDay = nil; [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&amp;newStartDateDay interval:NULL forDate:actualDate];并比较newStartDate,但使用beginDate。
      • 这就是为什么我为beginDateendDate 创建了两个用于排序的新变量。您的观点仍然有效,这些变量将删除它们的时间分量
      • 我只是想指出这一点——并不是说它会导致混乱,因为突然间所有事件都在 00:00 开始。
      • 很高兴指出。虽然我从不修改我正在过滤的日期,所以这不应该发生
      猜你喜欢
      • 1970-01-01
      • 2011-08-03
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多