两次国家统计局会议之间的天数

如何确定两个 NSDate值之间的天数(同时考虑时间) ?

NSDate值的形式与 [NSDate date]的形式无关。

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

exitDate = [NSDate date];

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

NSDate *now = [NSDate date];

现在我想实现以下几点:

-(int)numberOfDaysBetweenStartDate:exitDate andEndDate:now
100287 次浏览
NSDate *lastDate = [NSDate date];
NSDate *todaysDate = [NSDate date];
NSTimeInterval lastDiff = [lastDate timeIntervalSinceNow];
NSTimeInterval todaysDiff = [todaysDate timeIntervalSinceNow];
NSTimeInterval dateDiff = lastDiff - todaysDiff;

DateDiff 将是两个日期之间的秒数。除以一天中的秒数。

你是指日历日还是24小时周期?也就是说,星期二是在星期三前一天的晚上9点,上午6点,还是不到一天?

如果你指的是前者,它有点复杂,你将不得不诉诸于通过 NSCalendarNSDateComponent的操作,我不记得我的头顶。

如果您指的是后者,那么只需得到从参考日期开始的日期的时间间隔,从另一个中减去一个,然后除以24小时(24 * 60 * 60)得到近似的时间间隔,闰秒不包括在内。

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

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

编辑:

上面的解决方案非常棒,下面是作为 NSDate扩展的 Swift 版本:

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

根据用例的不同,您可能需要删除一些强制展开操作。

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

我找到的解决办法是:

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

在这里,我有效地四舍五入的第一次约会,从一天的开始,然后计算的差异,正如乔纳森建议以上..。

这是我找到的最好的解决办法。似乎利用了苹果认可的方法来确定 NSDates 之间的单位数量。

- (NSInteger)daysBetween:(NSDate *)dt1 and:(NSDate *)dt2
{
NSUInteger unitFlags = NSCalendarUnitDay;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
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

为什么不只是:

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

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

我的目标是知道,在两次约会之间(相差不到24小时) ,我是否有一个“加班”的一天 + 1:

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

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

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

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");
}

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

提姆

我需要两次约会之间的天数,包括开始的那天。 例如,2012年14月2日至2012年16月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;
}

请注意,提供日期的顺序并不重要,它总是返回一个正数。

我使用它作为 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);
}

另一种方法是:

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...方案相比,它的优势在于可以考虑时区,而且没有间隔短几秒或长一天的模糊性。

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

@ Brian

布莱恩的答案虽然不错,但只计算了24小时内的天数差异,而没有计算日历日的差异。例如,12月24日的23:59距离圣诞节只有1分钟的路程,对于许多应用程序来说,它被认为只有一天。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;
}
}

只是添加一个答案谁访问这个网页试图在 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
}

这个答案可以在下面方法的讨论部分找到 给你:

components(_:fromDate:toDate:options:)

我已经发布了一个开源类/库来实现这一点。

看一下 相对日期描述符,它可以用来获得如下时间差..。

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'

下面是布莱恩在 Swift 中的功能实现:

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
}

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

- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate

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

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
}


}

原始解决方案

斯威夫特的另一个解决方案。

如果你的目的是得到两次约会之间的确切日期,你可以这样解决这个问题:

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