两个NSDates之间的天数

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

NSDate值以[NSDate date]forms出现。

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

 exitDate = [NSDate date]; 

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

 NSDate *now = [NSDate date]; 

现在我想实现以下内容:

 -(int)numberOfDaysBetweenStartDate:exitDate andEndDate:now 

以下是我用来确定两个date之间的日历天数的实现:

 + (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]; } 

编辑:

上面的神奇解决scheme,下面的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 } } 

一点力量展开,你可能要删除取决于你的用例。

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

这是我find的最好的解决scheme。 似乎利用苹果认可的方法来确定任何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”作为一个单位标记。

为了certificate原来的博客,我在这里find了这个信息(尽pipe上面已经修正了一些小错误): http : //cocoamatic.blogspot.com/2010/09/nsdate-number-of-days-between-两dates.html?showComment = 1306198273659#c6501446329564880344

Swift 3.0更新

 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更新

 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 } } 

原始解决scheme

Swift中的另一个解决scheme。

如果您的目的是要获得两个date之间的确切date编号,您可以像这样解决这个问题:

 // 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 

我用这个作为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); } 

我需要包括开始date在内的两个date之间的天数。 例如14-2-2012和16-2-2012之间的天数将会产生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; } 

请注意,您提供date的顺序无关紧要。 它将始终返回一个正数。

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

那么dateDiff将是这两个date之间的秒数。 只需除以一天中的秒数。

@布赖恩

布赖恩的答案虽然不错,但只计算24小时内的差异,而不是日历天差异。 例如12月24日23:59距离圣诞节只有一分钟的时间,目前还有很多申请被认为是有一天还在。 Brian的daysBetween函数将返回0。

从Brian的原始实施和开始/结束的借用,我在我的程序中使用以下:( NSDate开始的一天和结束的一天 )

 - (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; } } 

另一种方法:

 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...scheme可以考虑时区,并且在一天的短或长的时间间隔内没有任何含糊之处。

而且比NSDateComponents方法更紧凑,更容易混淆。

只是为那些访问这个页面的人添加一个答案,试图在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 } 

这个答案在这里find,在下面的方法的讨论部分:

 components(_:fromDate:toDate:options:) 

以下是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 } 

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

如果你的意思是前者,这有点复杂,你不得不通过NSCalendarNSDateComponent来操纵,我不记得我的头顶。

如果你的意思是后者,只要从参考date开始计算date的时间间隔,从另一个中减去一个,然后除以24小时( 24 * 60 * 60 )即可得到近似的间隔,不包括闰秒。

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

我的目标是要知道,在两天之内(不到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"); } 

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

蒂姆

为什么不只是:

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

我find的解决scheme是:

 +(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在上面提到的差异。

我已经发布了一个开源的类/库来做到这一点。

看看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' 

为什么请注意使用下面的NSDate方法:

 - (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate 

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