首页 文章

两个NSDates之间的天数[重复]

提问于
浏览
148

这个问题在这里已有答案:

我怎样才能确定两个 NSDate 值之间的天数(考虑到时间)?

NSDate 值的格式为 [NSDate date] .

具体来说,当用户在我的iPhone应用程序中进入非活动状态时,我存储以下值:

exitDate = [NSDate date];

当他们打开应用程序备份时,我得到当前时间:

NSDate *now = [NSDate date];

现在我想实现以下内容:

-(int)numberOfDaysBetweenStartDate:exitDate andEndDate:now

16 回答

  • 5

    这是我用来确定两个日期之间的日历天数的实现:

    + (NSInteger)daysBetweenDate:(NSDate*)fromDateTime andDate:(NSDate*)toDateTime
    {
        NSDate *fromDate;
        NSDate *toDate;
    
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        [calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate
            interval:NULL forDate:fromDateTime];
        [calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate
            interval:NULL forDate:toDateTime];
    
        NSDateComponents *difference = [calendar components:NSCalendarUnitDay
            fromDate:fromDate toDate:toDate options:0];
    
        return [difference day];
    }
    

    EDIT:

    上面的神奇解决方案,这里的Swift版本作为 NSDate 的扩展:

    extension NSDate {
      func numberOfDaysUntilDateTime(toDateTime: NSDate, inTimeZone timeZone: NSTimeZone? = nil) -> Int {
        let calendar = NSCalendar.currentCalendar()
        if let timeZone = timeZone {
          calendar.timeZone = timeZone
        }
    
        var fromDate: NSDate?, toDate: NSDate?
    
        calendar.rangeOfUnit(.Day, startDate: &fromDate, interval: nil, forDate: self)
        calendar.rangeOfUnit(.Day, startDate: &toDate, interval: nil, forDate: toDateTime)
    
        let difference = calendar.components(.Day, fromDate: fromDate!, toDate: toDate!, options: [])
        return difference.day
      }
    }
    

    根据您的使用情况,您可能想要移除一些力量展开 .

    上述解决方案也适用于当前时区以外的时区,非常适合显示世界各地信息的应用程序 .

  • 116

    这是我发现的最佳解决方案 . 似乎利用Apple批准的方法来确定NSDates之间的任何数量的单位 .

    - (int)daysBetween:(NSDate *)dt1 and:(NSDate *)dt2 {
        NSUInteger unitFlags = NSDayCalendarUnit;
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
        NSDateComponents *components = [calendar components:unitFlags fromDate:dt1 toDate:dt2 options:0];
        return [components day]+1;
    }
    

    例如 . 如果您还想要几个月,那么您可以将'NSMonthCalendarUnit'作为unitFlag包含在内 .

    为了归功于原始博主,我在这里找到了这个信息(虽然我上面已经修改了一个小错误):http://cocoamatic.blogspot.com/2010/09/nsdate-number-of-days-between-two-dates.html?showComment=1306198273659#c6501446329564880344

  • 6

    Swift 3.0 Update

    extension Date {
    
        func differenceInDaysWithDate(date: Date) -> Int {
            let calendar = Calendar.current
    
            let date1 = calendar.startOfDay(for: self)
            let date2 = calendar.startOfDay(for: date)
    
            let components = calendar.dateComponents([.day], from: date1, to: date2)
            return components.day ?? 0
        }
    }
    

    Swift 2.0 Update

    extension NSDate {
    
        func differenceInDaysWithDate(date: NSDate) -> Int {
            let calendar: NSCalendar = NSCalendar.currentCalendar()
    
            let date1 = calendar.startOfDayForDate(self)
            let date2 = calendar.startOfDayForDate(date)
    
            let components = calendar.components(.Day, fromDate: date1, toDate: date2, options: [])
            return components.day
        }
    
    }
    

    Original Solution

    Swift的另一个解决方案 .

    如果您的目的是获取两个日期之间的确切日期数,您可以解决此问题,如下所示:

    // Assuming that firstDate and secondDate are defined
    // ...
    
    var calendar: NSCalendar = NSCalendar.currentCalendar()
    
    // Replace the hour (time) of both dates with 00:00
    let date1 = calendar.startOfDayForDate(firstDate)
    let date2 = calendar.startOfDayForDate(secondDate)
    
    let flags = NSCalendarUnit.DayCalendarUnit
    let components = calendar.components(flags, fromDate: date1, toDate: date2, options: nil)
    
    components.day  // This will return the number of day(s) between dates
    
  • 1

    我将它用作NSDate类的类别方法

    // returns number of days (absolute value) from another date (as number of midnights beween these dates)
    - (int)daysFromDate:(NSDate *)pDate {
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
        NSInteger startDay=[calendar ordinalityOfUnit:NSCalendarUnitDay
                                               inUnit:NSCalendarUnitEra
                                              forDate:[NSDate date]];
        NSInteger endDay=[calendar ordinalityOfUnit:NSCalendarUnitDay
                                             inUnit:NSCalendarUnitEra
                                            forDate:pDate];
        return abs(endDay-startDay);
    }
    
  • 8

    我需要两个日期之间的天数,包括开始日期 . 例如在2012年2月14日至2012年2月2日之间的几天将产生3的结果 .

    + (NSInteger)daysBetween:(NSDate *)dt1 and:(NSDate *)dt2 {
            NSUInteger unitFlags = NSDayCalendarUnit;
            NSCalendar* calendar = [NSCalendar currentCalendar];
            NSDateComponents *components = [calendar components:unitFlags fromDate:dt1 toDate:dt2 options:0];
            NSInteger daysBetween = abs([components day]);
        return daysBetween+1;
    }
    

    请注意,提供日期的顺序无关紧要 . 它将始终返回正数 .

  • 23
    NSDate *lastDate = [NSDate date];
    NSDate *todaysDate = [NSDate date];
    NSTimeInterval lastDiff = [lastDate timeIntervalSinceNow];
    NSTimeInterval todaysDiff = [todaysDate timeIntervalSinceNow];
    NSTimeInterval dateDiff = lastDiff - todaysDiff;
    

    dateDiff将是两个日期之间的秒数 . 只需除以一天中的秒数即可 .

  • 3

    @布赖恩

    布莱恩的答案很好,只计算24小时的天数差异,但不计算日历差异 . 例如12月24日23:59离圣诞节只有1分钟的距离,目的是许多申请被认为仍然是一天 . Brian的daysBetween函数将返回0 .

    借用Brian的原始实现和一天的开始/结束,我在我的程序中使用以下内容:(NSDate beginning of day and end of day

    - (NSDate *)beginningOfDay:(NSDate *)date
    {
        NSCalendar *cal = [NSCalendar currentCalendar];
        NSDateComponents *components = [cal components:( NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
        [components setHour:0];
        [components setMinute:0];
        [components setSecond:0];
        return [cal dateFromComponents:components];
    }
    
    - (NSDate *)endOfDay:(NSDate *)date
    {
        NSCalendar *cal = [NSCalendar currentCalendar];
        NSDateComponents *components = [cal components:( NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
        [components setHour:23];
        [components setMinute:59];
        [components setSecond:59];
        return [cal dateFromComponents:components];
    }
    
    - (int)daysBetween:(NSDate *)date1 and:(NSDate *)date2 {
        NSDate *beginningOfDate1 = [self beginningOfDay:date1];
        NSDate *endOfDate1 = [self endOfDay:date1];
        NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSDateComponents *beginningDayDiff = [calendar components:NSDayCalendarUnit fromDate:beginningOfDate1 toDate:date2 options:0];
        NSDateComponents *endDayDiff = [calendar components:NSDayCalendarUnit fromDate:endOfDate1 toDate:date2 options:0];
        if (beginningDayDiff.day > 0)
            return beginningDayDiff.day;
        else if (endDayDiff.day < 0)
            return endDayDiff.day;
        else {
            return 0;
        }
    }
    
  • 0

    另一种方法:

    NSDateFormatter* dayFmt = [[NSDateFormatter alloc] init];
    [dayFmt setTimeZone:<whatever time zone you want>];
    [dayFmt setDateFormat:@"g"];
    NSInteger firstDay = [[dayFmt stringFromDate:firstDate] integerValue];    
    NSInteger secondDay = [[dayFmt stringFromDate:secondDate] integerValue];
    NSInteger difference = secondDay - firstDay;
    

    具有优于 timeIntervalSince... 方案的优势,可以考虑时区,并且在一天的短时间或长时间内没有间隔的模糊性 .

    并且比NSDateComponents方法更紧凑,更少混乱 .

  • 1

    只需为访问此页面的人添加一个答案,试图在Swift中执行此操作 . 方法几乎相同 .

    private class func getDaysBetweenDates(startDate:NSDate, endDate:NSDate) -> NSInteger {
    
        var gregorian: NSCalendar = NSCalendar.currentCalendar();
        let flags = NSCalendarUnit.DayCalendarUnit
        let components = gregorian.components(flags, fromDate: startDate, toDate: endDate, options: nil)
    
        return components.day
    }
    

    在以下方法的讨论部分中找到了这个答案here

    components(_:fromDate:toDate:options:)
    
  • 3

    这是在Swift中Brian的函数的实现:

    class func daysBetweenThisDate(fromDateTime:NSDate, andThisDate toDateTime:NSDate)->Int?{
    
        var fromDate:NSDate? = nil
        var toDate:NSDate? = nil
    
        let calendar = NSCalendar.currentCalendar()
    
        calendar.rangeOfUnit(NSCalendarUnit.DayCalendarUnit, startDate: &fromDate, interval: nil, forDate: fromDateTime)
    
        calendar.rangeOfUnit(NSCalendarUnit.DayCalendarUnit, startDate: &toDate, interval: nil, forDate: toDateTime)
    
        if let from = fromDate {
    
            if let to = toDate {
    
                let difference = calendar.components(NSCalendarUnit.DayCalendarUnit, fromDate: from, toDate: to, options: NSCalendarOptions.allZeros)
    
                return difference.day
            }
        }
    
        return nil
    }
    
  • 0

    你的意思是日历日或24小时?即星期二上午6点,星期三上午6点,或不到一天?

    如果你的意思是前者,那么's a bit complicated and you'将不得不诉诸于 NSCalendarNSDateComponent 的操纵,我不记得我的头脑 .

    如果你的意思是后者,只需获取自参考日期以来的日期时间间隔,从另一个中减去一个,然后除以24小时( 24 * 60 * 60 )得到大致的间隔,不包括闰秒 .

  • 13

    有一个,不确定它是你想要的,但它可以帮助你们中的一些人,(帮帮我!!)

    我的目标是知道在两个日期之间(差异小于24小时)我是否有“过日”日1:

    我做了以下(我承认有点过时)

    NSDate *startDate = ...
    NSDate *endDate = ...
    

    NSDate已经被另一个NSDateFormatter格式化了(这个只是为了这个目的:)

    NSDateFormatter *dayFormater = [[NSDateFormatter alloc]init];
    [dayFormater setDateFormat:@"dd"];
    
    int startDateDay = [[dayFormater stringFromDate:startDate]intValue];
    
    int endDateDay = [[dayFormater stringFromDate:dateOn]intValue];
    
    if (endDateDay > startDateDay) {
        NSLog(@"day+1");
    } else {
        NSLog(@"same day");
    }
    

    也许这样的东西已经存在,但没有找到它

    蒂姆

  • 3

    我找到的解决方案是:

    +(NSInteger)getDaysDifferenceBetween:(NSDate *)dateA and:(NSDate *)dateB {
    
      if ([dateA isEqualToDate:dateB]) 
        return 0;
    
      NSCalendar * gregorian = 
            [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    
    
      NSDate * dateToRound = [dateA earlierDate:dateB];
      int flags = (NSYearCalendarUnit | NSMonthCalendarUnit |  NSDayCalendarUnit);
      NSDateComponents * dateComponents = 
             [gregorian components:flags fromDate:dateToRound];
    
    
      NSDate * roundedDate = [gregorian dateFromComponents:dateComponents];
    
      NSDate * otherDate = (dateToRound == dateA) ? dateB : dateA ;
    
      NSInteger diff = abs([roundedDate timeIntervalSinceDate:otherDate]);
    
      NSInteger daysDifference = floor(diff/(24 * 60 * 60));
    
      return daysDifference;
    }
    

    在这里,我有效地将第一个日期从一天开始,然后计算出Jonathan建议的差异......

  • 0

    我已经发布了一个开源类/库来做这件事 .

    看看RelativeDateDescriptor,可以用来获得如下的时差......

    RelativeDateDescriptor *descriptor = [[RelativeDateDescriptor alloc] initWithPriorDateDescriptionFormat:@"%@ ago" postDateDescriptionFormat:@"in %@"];
    
    // date1: 1st January 2000, 00:00:00
    // date2: 6th January 2000, 00:00:00
    [descriptor describeDate:date2 relativeTo:date1]; // Returns '5 days ago'
    [descriptor describeDate:date1 relativeTo:date2]; // Returns 'in 5 days'
    
  • 402

    为什么不呢:

    int days = [date1 timeIntervalSinceDate:date2]/24/60/60;
    
  • -1

    为什么要注意使用以下NSDate方法:

    - (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate
    

    这将返回两个日期之间的秒数,你可以除以86,400来获得天数!!

相关问题