How can I calculate the difference between two dates?
Objective CSwiftDateNsdateObjective C Problem Overview
How can I calculate the days between 1 Jan 2010 and (for example) 3 Feb 2010?
Objective C Solutions
Solution 1 - Objective C
NSDate *date1 = [NSDate dateWithString:@"2010-01-01 00:00:00 +0000"];
NSDate *date2 = [NSDate dateWithString:@"2010-02-03 00:00:00 +0000"];
NSTimeInterval secondsBetween = [date2 timeIntervalSinceDate:date1];
int numberOfDays = secondsBetween / 86400;
NSLog(@"There are %d days in between the two dates.", numberOfDays);
###EDIT:
Remember, NSDate
objects represent exact moments of time, they do not have any associated time-zone information. When you convert a string to a date using e.g. an NSDateFormatter
, the NSDateFormatter
converts the time from the configured timezone. Therefore, the number of seconds between two NSDate
objects will always be time-zone-agnostic.
Furthermore, this documentation specifies that Cocoa's implementation of time does not account for leap seconds, so if you require such accuracy, you will need to roll your own implementation.
Solution 2 - Objective C
You may want to use something like this:
NSDateComponents *components;
NSInteger days;
components = [[NSCalendar currentCalendar] components: NSDayCalendarUnit
fromDate: startDate toDate: endDate options: 0];
days = [components day];
I believe this method accounts for situations such as dates that span a change in daylight savings.
Solution 3 - Objective C
NSTimeInterval diff = [date2 timeIntervalSinceDate:date1]; // in seconds
where date1
and date2
are NSDate
's.
Also, note the definition of NSTimeInterval
:
typedef double NSTimeInterval;
Solution 4 - Objective C
Checkout this out. It takes care of daylight saving , leap year as it used iOS calendar to calculate.You can change the string and conditions to includes minutes with hours and days.
+(NSString*)remaningTime:(NSDate*)startDate endDate:(NSDate*)endDate
{
NSDateComponents *components;
NSInteger days;
NSInteger hour;
NSInteger minutes;
NSString *durationString;
components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute fromDate: startDate toDate: endDate options: 0];
days = [components day];
hour = [components hour];
minutes = [components minute];
if(days>0)
{
if(days>1)
durationString=[NSString stringWithFormat:@"%d days",days];
else
durationString=[NSString stringWithFormat:@"%d day",days];
return durationString;
}
if(hour>0)
{
if(hour>1)
durationString=[NSString stringWithFormat:@"%d hours",hour];
else
durationString=[NSString stringWithFormat:@"%d hour",hour];
return durationString;
}
if(minutes>0)
{
if(minutes>1)
durationString = [NSString stringWithFormat:@"%d minutes",minutes];
else
durationString = [NSString stringWithFormat:@"%d minute",minutes];
return durationString;
}
return @"";
}
Solution 5 - Objective C
With Swift 5 and iOS 12, according to your needs, you may use one of the two following ways to find the difference between two dates in days.
Calendar
's dateComponents(_:from:to:)
method
#1. Using import Foundation
let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let dateComponents = calendar.dateComponents([Calendar.Component.day], from: startDate, to: endDate)
print(dateComponents) // prints: day: 1621 isLeapMonth: false
print(String(describing: dateComponents.day)) // prints: Optional(1621)
DateComponentsFormatter
's string(from:to:)
method
#2. Using import Foundation
let calendar = Calendar.current
let startDate = calendar.date(from: DateComponents(year: 2010, month: 11, day: 22))!
let endDate = calendar.date(from: DateComponents(year: 2015, month: 5, day: 1))!
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.allowedUnits = [NSCalendar.Unit.day]
let elapsedTime = formatter.string(from: startDate, to: endDate)
print(String(describing: elapsedTime)) // prints: Optional("1,621 days")
Solution 6 - Objective C
Swift 4
Try this and see (date range with String):
// Start & End date string
let startingAt = "01/01/2018"
let endingAt = "08/03/2018"
// Sample date formatter
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
// start and end date object from string dates
var startDate = dateFormatter.date(from: startingAt) ?? Date()
let endDate = dateFormatter.date(from: endingAt) ?? Date()
// Actual operational logic
var dateRange: [String] = []
while startDate <= endDate {
let stringDate = dateFormatter.string(from: startDate)
startDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate) ?? Date()
dateRange.append(stringDate)
}
print("Resulting Array - \(dateRange)")
Swift 3
var date1 = Date(string: "2010-01-01 00:00:00 +0000")
var date2 = Date(string: "2010-02-03 00:00:00 +0000")
var secondsBetween: TimeInterval = date2.timeIntervalSince(date1)
var numberOfDays: Int = secondsBetween / 86400
print(numberOfDays)
Solution 7 - Objective C
You can find the difference by converting the date in seconds and take time interval since 1970 for this and then you can find the difference between two dates.
Solution 8 - Objective C
To find the difference, you need to get the current date and the date in the future. In the following case, I used 2 days for an example of the future date. Calculated by:
2 days
* 24 hours
* 60 minutes
* 60 seconds
. We expect the number of seconds in 2 days to be 172,800.
// Set the current and future date
let now = Date()
let nowPlus2Days = Date(timeInterval: 2*24*60*60, since: now)
// Get the number of seconds between these two dates
let secondsInterval = DateInterval(start: now, end: nowPlus2Days).duration
print(secondsInterval) // 172800.0
Solution 9 - Objective C
If you want all the units, not just the biggest one, use one of these 2 methods (based on @Ankish's answer):
Example output: 28 D | 23 H | 59 M | 59 S
+ (NSString *) remaningTime:(NSDate *)startDate endDate:(NSDate *)endDate
{
NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *components = [[NSCalendar currentCalendar] components:units fromDate: startDate toDate: endDate options: 0];
return [NSString stringWithFormat:@"%ti D | %ti H | %ti M | %ti S", [components day], [components hour], [components minute], [components second]];
}
+ (NSString *) timeFromNowUntil:(NSDate *)endDate
{
return [self remaningTime:[NSDate date] endDate:endDate];
}