【问题标题】:iOS: Compare two NSDate-s without time portioniOS:比较两个没有时间部分的 NSDate-s
【发布时间】:2011-09-09 07:19:40
【问题描述】:

我想比较两个日期:date1 和 date2

2011-06-06 12:59:48.994 Project[419:707] firstDate:2011-06-06 10:59:21 +0000
2011-06-06 12:59:49.004 Project[419:707] selectedData:2011-06-06 10:59:17 +0000

但是这些日期有不同的时间,当我使用 NSOrderedSame 时它不能正常工作,我该如何解决?

我的代码:

NSDate *firstDate = [[appDelegate.project objectAtIndex:i]objectAtIndex:3];
NSDate *secondDate = [[appDelegate.project objectAtIndex:i]objectAtIndex:4];

NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger comps = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);

NSDateComponents *date1Components = [calendar components:comps 
                                                            fromDate:firstDate];
NSDateComponents *date2Components = [calendar components:comps 
                                                            fromDate:secondDate];
NSDateComponents *date3Components = [calendar components:comps fromDate:appDelegate.selectedDate];

NSLog(@"firstDate:%@", [date1Components date]);
NSLog(@"secondDate:%@", [date2Components date]);
NSLog(@"selectedData:%@", [date3Components date]);

NSComparisonResult compareStart = [[date1Components date] compare: [date3Components date]]; 
NSComparisonResult compareEnd = [[date2Components date] compare: [date3Components date]]; 

if ((compareStart == NSOrderedAscending || compareStart == NSOrderedSame)
     && (compareEnd == NSOrderedDescending || compareEnd == NSOrderedSame))

{
    NSLog(@"inside");

然后我想在 date1

【问题讨论】:

  • 代替NSLog(@"firstDate:%@", [date1Components date]);试试NSLog(@"firstDate:%@", [calendar dateFromComponents:date1Components]);有什么变化吗?
  • 现在是 2011-06-05 22:00:00 +0000 为什么?????
  • 可能是一些时区/夏令时魔法
  • 一切正常:我写 [date1Components setTimeZone:[ NSTimeZone timeZoneForSecondsFromGMT:(+0*3600) ] ] ;和 NSComparisonResult compareStart = [[calendar dateFromComponents:date1Components] compare: [calendar dateFromComponents:date3Components]];谢谢...

标签: objective-c ios cocoa-touch nsdate


【解决方案1】:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger comps = (NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear);

NSDateComponents *date1Components = [calendar components:comps 
                                                fromDate: date1];
NSDateComponents *date2Components = [calendar components:comps 
                                                fromDate: date2];

date1 = [calendar dateFromComponents:date1Components];
date2 = [calendar dateFromComponents:date2Components];

NSComparisonResult result = [date1 compare:date2];
if (result == NSOrderedAscending) {
} else if (result == NSOrderedDescending) {
}  else {
    //the same
}

还有另一种方便的方法可以为给定日期创建代表给定单位开始的日期:[aCalendar rangeOfUnit:startDate:interval:forDate:]
要说明此方法的工作原理,请参阅此代码,它可以轻松地为给定日期(此处:现在)创建一天、一周、一个月和一年的开始日期。

NSDate *now = [NSDate date];
NSDate *startOfToday = nil;
NSDate *startOfThisWeek = nil;
NSDate *startOfThisMonth = nil;
NSDate *startOfThisYear = nil;
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startOfToday interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSWeekCalendarUnit startDate:&startOfThisWeek interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSMonthCalendarUnit startDate:&startOfThisMonth interval:NULL forDate:now];
[[NSCalendar currentCalendar] rangeOfUnit:NSYearCalendarUnit startDate:&startOfThisYear interval:NULL forDate:now];

NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterFullStyle];
[formatter setTimeStyle:NSDateFormatterFullStyle];

NSLog(@"%@", [formatter stringFromDate:now]);
NSLog(@"%@", [formatter stringFromDate:startOfToday]);
NSLog(@"%@", [formatter stringFromDate:startOfThisWeek]);
NSLog(@"%@", [formatter stringFromDate:startOfThisMonth]);
NSLog(@"%@", [formatter stringFromDate:startOfThisYear]);

结果:

Thursday, July 12, 2012, 4:36:07 PM Central European Summer Time 
Thursday, July 12, 2012, 12:00:00 AM Central European Summer Time 
Sunday, July 8, 2012, 12:00:00 AM Central European Summer Time 
Sunday, July 1, 2012, 12:00:00 AM Central European Summer Time 
Sunday, January 1, 2012, 12:00:00 AM Central European Standard Time

这使我们可以将第一个代码缩短为:

[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&date1 interval:NULL forDate:date1];
[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&date2 interval:NULL forDate:date2];

NSComparisonResult result = [date1 compare:date2];
if (result == NSOrderedAscending) {
} else if (result == NSOrderedDescending) {
}  else {
    //the same
}

请注意,在此代码中,date1date2 将被覆盖。或者,您可以传递对 startDate 的另一个 NSDate 指针的引用,如上面的代码所示,其中 now 保持不变。

【讨论】:

  • 我有一个警告:“NSDateComponents 可能无法响应比较”
  • 第一个实现是否覆盖 date1 和 date2,似乎它将小时、分钟和秒设置为 0,因为: date1 = [calendar dateFromComponents:date1Components]; date2 = [日历 dateFromComponents:date2Components];
  • @McGar 是的,它将新对象分配给变量。
  • 至少在 2016 年,NSCalendar 有许多有用的日期比较方法。
  • 2020 年对我来说仍然有帮助。我发现 [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit startDate:&startOfToday interval:NULL forDate:now]; 在我的应用中很有用。
【解决方案2】:

我使用了另一种方法与 NSDateFormatter 和字符串比较,不如 NSDate compare 方法,但编写速度更快,并且足够灵活,可以进行各种比较:

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"yyyy-MM-dd"];

if ([[dateFormat stringFromDate:date1] isEqualToString:[dateFormat stringFromDate:date2]])
{
    //It's the same day
}

【讨论】:

    【解决方案3】:

    Swift 版本,比较日期并忽略它们的时间。

    let dateExam1:NSDate = NSDate.init(timeIntervalSinceNow: 300)
    let dateExam2:NSDate = NSDate.init(timeIntervalSinceNow: 10000)
    
    let currCalendar = NSCalendar.currentCalendar()
    
    let dateCompanent1:NSDateComponents = currCalendar.components([.Year,.Month,.Day], fromDate: dateExam1)
    let dateCompanent2:NSDateComponents = currCalendar.components([.Year,.Month,.Day], fromDate: dateExam2)
    
    let date1WithoutTime:NSDate? = currCalendar .dateFromComponents(dateCompanent1)
    let date2WithoutTime:NSDate? = currCalendar .dateFromComponents(dateCompanent2)
    if (date1WithoutTime != nil) && (date2WithoutTime != nil)
    {
        let dateCompResult:NSComparisonResult = date1WithoutTime!.compare(date2WithoutTime!)
        if (dateCompResult == NSComparisonResult.OrderedSame)
        {
            print("Same Dates")
        }
        else
        {
            print("Different Dates")
        }
    }
    

    【讨论】:

      【解决方案4】:

      好吧,原来的问题问了几年后,但可能值得一提的是,NSCalendar 现在有许多方法可以让某些日期比较问题更加直接:

      NSCalendar *currentCalendar = [NSCalendar currentCalendar];
      Bool sameDay = [currentCalendar isDate:dateA inSameDayAsDate:dateB];
      

      【讨论】:

        【解决方案5】:

        更新@LuAndre 快速回答 5

            let dateExam1 = Date(timeIntervalSinceNow: 300)
            let dateExam2 = Date(timeIntervalSinceNow: 10000)
        
            let currCalendar = Calendar.current
        
            let dateCompanent1 = currCalendar.dateComponents([.year,.month,.day], from: dateExam1)
            let dateCompanent2 = currCalendar.dateComponents([.year,.month,.day], from: dateExam2)
        
        
            if  let date1WithoutTime = currCalendar.date(from:dateCompanent1), let dateCompanent2 = currCalendar.date(from:dateCompanent2) {
                    let dateCompResult = date1WithoutTime.compare(dateCompanent2)
                    if (dateCompResult == ComparisonResult.orderedSame)
                    {
                        print("Same Dates")
                    }
                    else
                    {
                        print("Different Dates")
                    }
                
            }
        

        【讨论】:

          猜你喜欢
          • 2012-02-18
          • 2010-12-23
          • 1970-01-01
          • 2012-05-30
          • 1970-01-01
          • 2012-07-22
          • 2013-07-25
          • 2011-08-03
          • 2011-07-09
          相关资源
          最近更新 更多