Calculating the number of days between two dates in Objective-C

Objective CIosNsstringNsdate

Objective C Problem Overview


> Possible Duplicate:
> https://stackoverflow.com/questions/2548008/how-can-i-compare-two-dates-return-a-number-of-days

I have two dates (as NSString in the form "yyyy-mm-dd"), for example:

NSString *start = "2010-11-01";
NSString *end = "2010-12-01";

I'd like to implement:

- (int)numberOfDaysBetween:(NSString *)startDate and:(NSString *)endDate {

}

Objective C Solutions


Solution 1 - Objective C

NSString *start = @"2010-09-01";
NSString *end = @"2010-12-01";

NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:@"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];

NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay
                                                    fromDate:startDate
                                                      toDate:endDate
                                                     options:0];

components now holds the difference.

NSLog(@"%ld", [components day]);

Solution 2 - Objective C

There is a whole guide to Date and Time Programming. Here is a relevant section which gives you a hint about what to do.

It's where the example code comes from in the other question.

Try and write something based on that and then come back if you have specific questions.

Edit

Okay. Here is how I would write the code in it's most basic form.

First, I would extend NSDate.

The header file:

//  NSDate+ADNExtensions.h

#import <Cocoa/Cocoa.h>


@interface NSDate (ADNExtensions)

- (NSInteger)numberOfDaysUntil:(NSDate *)aDate;

@end

The implementation file:

//  NSDate+ADNExtensions.m

#import "NSDate+ADNExtensions.h"


@implementation NSDate (ADNExtensions)


- (NSInteger)numberOfDaysUntil:(NSDate *)aDate {
    NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    
    NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit fromDate:self toDate:aDate options:0];
    
    return [components day];
}


@end

This is very rough code. There is no error checking or validating that the second date is later than the first.

And then I would use it like this (running on a 64-bit, Garbage Collected environment):

NSDate *startDate = [NSDate dateWithString:@"2010-11-01 00:00:00 +0000"];
NSDate *endDate = [NSDate dateWithString:@"2010-11-02 00:00:00 +0000"];

NSInteger difference = [startDate numberOfDaysUntil:endDate];

NSLog(@"Diff = %ld", difference);

This is such a shame, because you would have learned a lot more by posting your code and the incorrect outputs and getting more specific help. But if you just want to be a cut-and-paste programmer; take this code and good luck to you.

Solution 3 - Objective C

Swift 4 implementation

Method call :

let numberOfDays = daysBetweenDates(startDate: fileCreatedDate,endDate: date)

Method Implementation:

 func daysBetweenDates(startDate: Date, endDate: Date) -> Int {
        let daysBetween = Calendar.current.dateComponents([.day], from: startDate, to: endDate)
        print(daysBetween.day!)
        return daysBetween.day!
  }

Objective C implementation:

Method Call:

int numberOfDaysSinceFileCreation = [self daysBetweenDates: fileCreatedDate
                                                                   currentDate: today];

Method Implementation:

- (int) daysBetweenDates: (NSDate *)startDate currentDate: (NSDate *)endDate
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *dateComponent = [calendar components:NSCalendarUnitDay fromDate:startDate toDate:endDate options:0];
    
    int totalDays = (int)dateComponent.day;
    return totalDays;
    
}

Solution 4 - Objective C

This code seems to work nicely in Swift 2:

func daysBetweenDate(startDate: NSDate, endDate: NSDate) -> Int
{
    let calendar = NSCalendar.currentCalendar()

    let components = calendar.components([.Day], fromDate: startDate, toDate: endDate, options: [])

    return components.day
}

Solution 5 - Objective C

ObjC Code:

NSDateComponents *dateComponent = [calender components:NSCalendarUnitDay fromDate:startDate toDate:endDate options:0];

Result:

int totalDays = (int)dateComponent.day;

Solution 6 - Objective C

Swift 3:

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let start = formatter.date(from: "2010-09-01")!
let end = formatter.date(from: "2010-12-01")!
let days = Calendar.current.dateComponents([.day], from: start, to: end).day!

Solution 7 - Objective C

The examples mentioned above represent only half picture of the solution because most of the solution only take date value (e.g: 2010-11-01) into account when calculating the difference however in-real world scenario NSDate instance always come together with time and impact the difference on the result as well.

Now, let's talk about the accepted solution where user defined the two dates but not time for them.

NSString *start = @"2010-09-01";
NSString *end = @"2010-09-02";

NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:@"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end]; 

Here the time for both dates would be same because no time has been provided for them which means it doesn't impact on the difference calculation.

startDate "2010-09-01 12:00 AM"
endDate "2010-09-02 12:00 AM"

And the result would be days = 1

Now let's add a specific time for both dates:

startDate "2010-09-01 02:00 PM"
endDate "2010-09-02 02:00 AM"

After adding a specific time the result would change. Now days = 0 even though day defined in the dates are different. It's because the time difference between the two dates is less than 24 hours.

This calculation method is gonna work fine as long as:

  • Desired result is based on time difference.

Or

  • Time is not defined for difference.

However, if you wanna calculate the days difference based on calendar date change then there would a problem because in the above example even though calendar date changed but the result would be days = 0. It's because of the time difference is less than 24 hours.

So, how we can calculate the days difference based on calendar date change. Here is the Apple suggested way of doing it:

@implementation NSCalendar (MySpecialCalculations)
- (NSInteger)daysWithinEraFromDate:(NSDate *)startDate toDate:(NSDate *)endDate {
     NSInteger startDay=[self ordinalityOfUnit:NSDayCalendarUnit inUnit: NSEraCalendarUnit forDate:startDate];
     NSInteger endDay=[self ordinalityOfUnit:NSDayCalendarUnit  inUnit: NSEraCalendarUnit forDate:endDate];
     return endDay - startDay;
}
@end 

More details are available here

My two cent on the topic to represent the remaining half of the picture.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCodeGuyView Question on Stackoverflow
Solution 1 - Objective CvikingosegundoView Answer on Stackoverflow
Solution 2 - Objective CAbizernView Answer on Stackoverflow
Solution 3 - Objective CNaishtaView Answer on Stackoverflow
Solution 4 - Objective CiphaawView Answer on Stackoverflow
Solution 5 - Objective CGobi MView Answer on Stackoverflow
Solution 6 - Objective CBlixtView Answer on Stackoverflow
Solution 7 - Objective CEEJView Answer on Stackoverflow