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

时间:2022-08-25 18:22:21

This question already has an answer here:

这个问题已经有了答案:

How could I determine the number of days between two NSDate values (taking into consideration time as well)?

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

The NSDate values are in whatever form [NSDate date] takes.

NSDate值的形式是[NSDate]。

Specifically, when a user enters the inactive state in my iPhone app, I store the following value:

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

exitDate = [NSDate date];

And when they open the app back up, I get the current time:

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

NSDate *now = [NSDate date];

Now I'd like to implement the following:

现在我想实施以下内容:

-(int)numberOfDaysBetweenStartDate:exitDate andEndDate:now

16 个解决方案

#1


397  

Here's an implementation I used to determine the number of calendar days between two dates:

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

+ (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:

编辑:

Fantastic solution above, here's Swift version below as an extension on NSDate:

以上极好的解决方案,以下是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
  }
}

A bit of force unwrapping going on which you may want to remove depending on your use case.

根据您的用例,您可能想要移除的一些力正在展开。

The above solution also works for time zones other than the current time zone, perfect for an app that shows information about places all around the world.

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

#2


114  

Here's the best solution I've found. Seems to utilize the Apple approved method for determining any amount of units between NSDates.

这是我找到的最好的解决办法。似乎在利用苹果批准的方法来确定nsdate之间的任何数量。

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

E.g. if you want months as well, then you could include 'NSMonthCalendarUnit' as a unitFlag.

例如,如果你也想要几个月,你可以把“nsmonth calendar”作为unitFlag。

To credit the original blogger, I found this info here (although there was a slight mistake that I've fixed above): http://cocoamatic.blogspot.com/2010/09/nsdate-number-of-days-between-two-dates.html?showComment=1306198273659#c6501446329564880344

为了感谢最初的博主,我在这里找到了这个信息(尽管我在上面修正了一个小错误):http://cocoamatic.blogspot.com/2010/09/nsdate-ofdaybetween -two-dates.html? showcomment= 1306198273659#c6501446329564880344

#3


22  

Swift 3.0 Update

斯威夫特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 Update

斯威夫特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
    }

}

Original Solution

原来的解决方案

Another solution in Swift.

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

If your purpose is to get the exact day number between two dates, you can work around this issue like this:

如果你的目的是在两个日期之间得到确切的日期,你可以这样处理这个问题:

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

#4


12  

I use this as category method for NSDate class

我将它用作NSDate类的category方法

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

#5


8  

I needed the number of days between two dates including the beginning day. e.g. days between 14-2-2012 and 16-2-2012 would produce a result of 3.

我需要两个日期之间的天数,包括开始日。例如,在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;
}

Note that it doesn't matter in which order you provide the dates. It will always return a positive number.

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

#6


6  

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

dateDiff will then be the number of second between the two dates. Just divide by the number of seconds in a day.

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

#7


5  

@Brian

@Brian

Brian's answer while good, only calculates difference in days in terms of 24h chunks, but not calendar day differences. For example 23:59 on Dec 24th is only 1 minute away from Christmas Day, for the purpose of many application that is considered one day still. Brian's daysBetween function would return 0.

Brian的回答虽然很好,但只以24小时为单位计算天数的差异,而不计算日历天数的差异。例如,12月24日的23:59距离圣诞节只有1分钟的时间,对于很多仍然被认为是一天的应用来说。Brian的间隔时间函数将返回0。

Borrowing from Brian's original implementation and beginning/end of day, I use the following in my program: (NSDate beginning of day and end of day)

借用Brian的原始实现和开始/结束,我在我的程序中使用了以下内容:

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

#8


3  

Another approach:

另一种方法:

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;

Has the advantage over the timeIntervalSince... scheme that timezone can be taken into account, and there's no ambiguity with intervals a few seconds short or long of one day.

从…开始有优势吗?可以考虑时区的规划,并且间隔几秒钟或长一秒的时间间隔不会有歧义。

And a bit more compact and less confusing than the NSDateComponents approaches.

与NSDateComponents的方法相比,它更紧凑,更容易理解。

#9


3  

Just adding an answer for those who visit this page trying to do this in Swift. The approach is pretty much the same.

只是为那些访问本页的人添加一个答案。方法基本相同。

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
}

This answer was found here, in the discussion section of the following method:

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

components(_:fromDate:toDate:options:)

#10


3  

Here is an implementation of Brian's function in Swift:

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

#11


1  

Do you mean calendar days or 24-hour periods? i.e. is Tuesday at 9PM a day before Wednesday at 6AM, or less than one day?

你是指日历日还是24小时?例如,星期二是在星期三的前一天晚上9点,还是在星期三早上6点,还是在一天之内?

If you mean the former, it's a bit complicated and you'll have to resort to manipulations via NSCalendar and NSDateComponent which I don't recall off the top of my head.

如果你指的是前者,它有点复杂你需要通过NSCalendar和NSDateComponent进行操作我记不太清了。

If you mean the latter, just get the dates' time intervals since the reference date, subtract one from the other, and divide by 24 hours (24 * 60 * 60) to get the approximate interval, leap seconds not included.

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

#12


1  

Got one, not sure it's exactly what you want, but it could help some of you, (helped me!!)

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

My goal was to know if, between two date (less than 24h difference) i had a "overday" day+1:

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

i did the following (a bit archaic i admit)

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

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

NSDate already formatted by another NSDateFormatter (this one is just for this purpose :)

NSDate已经被另一个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");
}

maybe something like this already exist, but didn't find it

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

Tim

蒂姆

#13


0  

The solution I found was:

我找到的解决办法是:

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

Here I am effectively rounding the first date to start from the beginning of the day and then calculating the difference as Jonathan is suggesting above...

在这里,我有效地完成了第一次约会,从一天开始,然后计算差额,正如乔纳森在上面所说的……

#14


0  

I have published an open-source class/library to do just this.

为此,我发布了一个开源类/库。

Have a look at RelativeDateDescriptor, which can be used to obtain the time difference as follows...

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

#15


0  

Why not just:

为什么不直接:

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

#16


-1  

Why note use the following NSDate method:

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

- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate

This will return the number of seconds between your two dates and you can divide by 86,400 to get the number of days !!

这将返回两个约会之间的秒数,你可以除以86400得到天数!

#1


397  

Here's an implementation I used to determine the number of calendar days between two dates:

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

+ (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:

编辑:

Fantastic solution above, here's Swift version below as an extension on NSDate:

以上极好的解决方案,以下是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
  }
}

A bit of force unwrapping going on which you may want to remove depending on your use case.

根据您的用例,您可能想要移除的一些力正在展开。

The above solution also works for time zones other than the current time zone, perfect for an app that shows information about places all around the world.

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

#2


114  

Here's the best solution I've found. Seems to utilize the Apple approved method for determining any amount of units between NSDates.

这是我找到的最好的解决办法。似乎在利用苹果批准的方法来确定nsdate之间的任何数量。

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

E.g. if you want months as well, then you could include 'NSMonthCalendarUnit' as a unitFlag.

例如,如果你也想要几个月,你可以把“nsmonth calendar”作为unitFlag。

To credit the original blogger, I found this info here (although there was a slight mistake that I've fixed above): http://cocoamatic.blogspot.com/2010/09/nsdate-number-of-days-between-two-dates.html?showComment=1306198273659#c6501446329564880344

为了感谢最初的博主,我在这里找到了这个信息(尽管我在上面修正了一个小错误):http://cocoamatic.blogspot.com/2010/09/nsdate-ofdaybetween -two-dates.html? showcomment= 1306198273659#c6501446329564880344

#3


22  

Swift 3.0 Update

斯威夫特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 Update

斯威夫特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
    }

}

Original Solution

原来的解决方案

Another solution in Swift.

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

If your purpose is to get the exact day number between two dates, you can work around this issue like this:

如果你的目的是在两个日期之间得到确切的日期,你可以这样处理这个问题:

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

#4


12  

I use this as category method for NSDate class

我将它用作NSDate类的category方法

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

#5


8  

I needed the number of days between two dates including the beginning day. e.g. days between 14-2-2012 and 16-2-2012 would produce a result of 3.

我需要两个日期之间的天数,包括开始日。例如,在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;
}

Note that it doesn't matter in which order you provide the dates. It will always return a positive number.

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

#6


6  

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

dateDiff will then be the number of second between the two dates. Just divide by the number of seconds in a day.

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

#7


5  

@Brian

@Brian

Brian's answer while good, only calculates difference in days in terms of 24h chunks, but not calendar day differences. For example 23:59 on Dec 24th is only 1 minute away from Christmas Day, for the purpose of many application that is considered one day still. Brian's daysBetween function would return 0.

Brian的回答虽然很好,但只以24小时为单位计算天数的差异,而不计算日历天数的差异。例如,12月24日的23:59距离圣诞节只有1分钟的时间,对于很多仍然被认为是一天的应用来说。Brian的间隔时间函数将返回0。

Borrowing from Brian's original implementation and beginning/end of day, I use the following in my program: (NSDate beginning of day and end of day)

借用Brian的原始实现和开始/结束,我在我的程序中使用了以下内容:

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

#8


3  

Another approach:

另一种方法:

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;

Has the advantage over the timeIntervalSince... scheme that timezone can be taken into account, and there's no ambiguity with intervals a few seconds short or long of one day.

从…开始有优势吗?可以考虑时区的规划,并且间隔几秒钟或长一秒的时间间隔不会有歧义。

And a bit more compact and less confusing than the NSDateComponents approaches.

与NSDateComponents的方法相比,它更紧凑,更容易理解。

#9


3  

Just adding an answer for those who visit this page trying to do this in Swift. The approach is pretty much the same.

只是为那些访问本页的人添加一个答案。方法基本相同。

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
}

This answer was found here, in the discussion section of the following method:

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

components(_:fromDate:toDate:options:)

#10


3  

Here is an implementation of Brian's function in Swift:

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

#11


1  

Do you mean calendar days or 24-hour periods? i.e. is Tuesday at 9PM a day before Wednesday at 6AM, or less than one day?

你是指日历日还是24小时?例如,星期二是在星期三的前一天晚上9点,还是在星期三早上6点,还是在一天之内?

If you mean the former, it's a bit complicated and you'll have to resort to manipulations via NSCalendar and NSDateComponent which I don't recall off the top of my head.

如果你指的是前者,它有点复杂你需要通过NSCalendar和NSDateComponent进行操作我记不太清了。

If you mean the latter, just get the dates' time intervals since the reference date, subtract one from the other, and divide by 24 hours (24 * 60 * 60) to get the approximate interval, leap seconds not included.

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

#12


1  

Got one, not sure it's exactly what you want, but it could help some of you, (helped me!!)

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

My goal was to know if, between two date (less than 24h difference) i had a "overday" day+1:

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

i did the following (a bit archaic i admit)

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

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

NSDate already formatted by another NSDateFormatter (this one is just for this purpose :)

NSDate已经被另一个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");
}

maybe something like this already exist, but didn't find it

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

Tim

蒂姆

#13


0  

The solution I found was:

我找到的解决办法是:

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

Here I am effectively rounding the first date to start from the beginning of the day and then calculating the difference as Jonathan is suggesting above...

在这里,我有效地完成了第一次约会,从一天开始,然后计算差额,正如乔纳森在上面所说的……

#14


0  

I have published an open-source class/library to do just this.

为此,我发布了一个开源类/库。

Have a look at RelativeDateDescriptor, which can be used to obtain the time difference as follows...

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

#15


0  

Why not just:

为什么不直接:

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

#16


-1  

Why note use the following NSDate method:

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

- (NSTimeInterval)timeIntervalSinceDate:(NSDate *)anotherDate

This will return the number of seconds between your two dates and you can divide by 86,400 to get the number of days !!

这将返回两个约会之间的秒数,你可以除以86400得到天数!