Calculating the number of days between two dates in Objective-C
Objective CIosNsstringNsdateObjective 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.