Get the exact difference between 2 dates for a single NSDateComponent

Get the exact difference between 2 dates for a single NSDateComponent

How can I get the exact difference (in decimal) between 2 values of NSDate.

Eg. Jan 15 2016 to Jul 15 2017 = 1.5 Years.

I can use something like: NSCalendar.currentCalendar().components(NSCalendarUnit.CalendarUnitYear, fromDate: date1, toDate: date1, options: nil).year but this gives me absolute values. i.e. for above example it would give me 1 Year. Is it possible to get exact values correct to at least a few decimal places?


The terms you've used here are misleading. When you say "absolute" you mean "integral." And when you say "exact" you mean "within some desired precision."

Let's say the precision you wanted was 2 decimal places, so we'd need to measure a year to 1%. That's larger than a day, so tracking days is sufficient. If you needed more precision, then you could expand this technique, but if you push it too far, "year" gets more tricky, and you have to start asking what you mean by "a year."

Avoid asking this question when you can. Many answers here say things like "there are 365.25 days in a year." But try adding "365.25 * 24 hours" to "right now" and see if you get "the same date and time next year." While it may seem correct "on average," it is actually wrong 100% of the time for calendar dates. (It works out here because it's within 1%, but so would 365, 366, or even 363.)

We avoid this madness by saying "1% is close enough for this problem."

// What calendar do you *really* mean here? The user's current calendar, 
// or the Gregorian calendar? The below code should work for any calendar,
// because every calendar's year is made up of some number of days, but it's
// worth considering if you really mean (and are testing) arbitrary calendars.
// If you mean "Gregorian," then use NSCalendar(identifier: NSCalendarIdentifierGregorian)!
let calendar = NSCalendar.currentCalendar()

// Determine how many integral days are between the dates
let diff = calendar.components(.Day, fromDate: date1, toDate: date2, options: [])

// Determine how many days are in a year. If you really meant "Gregorian" above, and
// so used calendarWithIdentifer rather than currentCalendar, you can estimate 365 here.
// Being within one day is inside the noise floor of 1%.
// Yes, this is harder than you'd think. This is based on MartinR's code: http://stackoverflow.com/a/16812482/97337
var startOfYear: NSDate? = nil
var lengthOfYear = NSTimeInterval(0)
calendar.rangeOfUnit(.Year, startDate: &startOfYear, interval: &lengthOfYear, forDate: date1)
let endOfYear = startOfYear!.dateByAddingTimeInterval(lengthOfYear)
let daysInYear = calendar.components(.Day, fromDate: startOfYear!, toDate: endOfYear, options: []).day

// Divide
let fracDiff = Double(diff.day) / Double(daysInYear)

That said, in most cases you shouldn't be doing this. Since iOS 8, the preferred tool is NSDateComponentsFormatter. You won't get this precise format (i.e. fractional years), but you'll get a nicely localized result that takes most issues into account across different cultures.

let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = .Full
formatter.includesApproximationPhrase = true
formatter.allowedUnits = [.Year, .Month]
formatter.allowsFractionalUnits = true

formatter.stringFromDate(date1, toDate: date2)
// About 1 year, 6 months

Developing for Apple Watch: Create Native watchOS Apps with the , Using this method, you'll be able to compute the dates for Time Travel. let's use this method to find the minimum and maximum dates that Time Travel will cover: Extension/ComplicationController.swift var timeTravelBeginDate: NSDate beginning offset to subtract one day from midnight of the current day and 2 to add​  The “d” returns the number of full days between the two dates. Difference in weeks In this example, the start date is in cell D13, and the end date is in E13.


Since you mentioned that your goal is something you can display to users as a meaningful indication of the time between two dates, you might find it easier to use NSDateComponentsFormatter. For example:

let dateStr1 = "Jan 15 2016"
let dateStr2 = "Jul 15 2017"

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MMM dd yyyy"

if let date1 = dateFormatter.dateFromString(dateStr1),
    let date2 = dateFormatter.dateFromString(dateStr2) {
    let dateComponentsFormatter = NSDateComponentsFormatter()
    dateComponentsFormatter.allowedUnits = [.Year, .Month]
    dateComponentsFormatter.unitsStyle = .Full

    let difference = dateComponentsFormatter.stringFromDate(date1, toDate: date2)
}

This gives you a string that reads "1 year, 6 months". It's not exactly what you specified as your goal, but it's a clear indication for users and avoids a lot of complexity. There's a property on NSDateComponentsFormatter called allowsFractionalUnits that's supposed to lead to results like "1.5 years", but it doesn't seem to work right now. (Even if you limit the allowedUnits to only .Year, you still don't get a fractional year. I'm off to file a bug with Apple...). You can tweak allowedUnits to get whatever granularity you like, and use includesApproximationPhrase to have the class add a localized version of "About..." to the resulting string if it's not precise. If you have some flexibility in your final format, this would be a really good solution.

components:fromDate:toDate:options:, Returns the difference between two supplied dates as date components. the specified components are incremented and wrap around to zero/one on shows how to get the approximate number of months and days between two dates using​  How many days, months, and years are there between two dates? See how long remains before a deadline or exactly when those 30 days are up. Add your company logo to our printable calendars. Weekday Calculator – What Day is this Date? Calendar Generator – Create a calendar for any year.


There isn't a perfect answer to this question. Different years are slightly different lengths. You have to make some assumptions.

If you assume 365.2425 days per year, with each day having 24 hours, then the calculation is trivial:

let secondsPerYear: NSTimeInterval = NSTimeInterval(365.2425 * 24 * 60 * 60)
let secondsBetweenDates = 
  date2.timeIntervalSinceReferenceDate - date1.timeIntervalSinceReferenceDate;
let yearsBetweenDates = secondsBetweenDates / secondPerYear

But there are lots of edge cases and weirdness to deal with. Because of leap years, some years have 365 days, and some have 366. Then there's leap seconds.

If you get rid of months in @CodeDifferent's answer then you'll get an answer that allows for leap days between the dates.

But, as Code Different pointed out, his answer as written actually gives answers that seem more accurate, even though they are not. (A difference of 3 months will always yield .25 years, and will ignore longer/shorter months. Is that the right thing to do? Depends on your goal and your assumptions.)

Learning IOS Development: A Hands-on Guide to the Fundamentals of , The other region setting is Calendar, and it controls how NSDate objects are converted to dates as well Some calendars, such as the Buddhist one, have 13 months. The first step to seeing Arabic numbers and dates is to set the correct region. 2. Generate a format string for how you want to display the date (​optional). 3. i want to hav, how many months are there b/w two dates. m using ,, months_between_dates fn. but the problem is if i give two dates as 22.06.2007 and 05.07.2007. it gives me 1 month but it is actually not complete month. i want to hav accurate differe


According to NASA, there are 365.2422 days per year on average. Here, I round that up to 365.25 days per year:

let components = NSCalendar.currentCalendar().components([.Year, .Month, .Day], fromDate: fromDate, toDate: toDate, options: [])

var totalYears = Double(components.year)
totalYears += Double(components.month) / 12.0
totalYears += Double(components.day) / 365.25

Obviously, this depends on your assumptions. If you want to count of leap days between fromDate and toDate, it will be more complicated.

Some sample outputs:

From date      To date        Total Years
------------   ------------   ------------
Jan 15, 2016   Jul 15, 2017   1.5
Jan 15, 2016   Apr 14, 2016   0.25
Jan 15, 2016   Aug 15, 2017   1.5833
Jan 15, 2016   Jan 14, 2018   1.9988

Pro iOS Apps Performance Optimization, The intersect method will find same items inside two sets and put them into the Moreover, the correct approach may save you a few hours of coding when trying to Theoretical Issues of Measuring Algorithmic Performance I've shown you one algorithm's performance using NSLog and NSDate in Listings 5–1 and 5–​2. calculating the difference between 2 dates. Follow 492 views (last 30 days) antonet on 25 May 2012. Vote. 0 ⋮ Vote. 0. Commented: Rosanna on 11 Oct 2018


Performing Calendar Calculations, Performing Calendar Calculations. NSDate provides the absolute scale and epoch for dates and times, which can then be rendered into a  I guess the straight forward way of getting the days between the two dates and dividing by 30 is not what you want. In that case, if you are doing this in a calculation/analytic view, you can use the _SYS_BI.M_TIME_DIMENSION table to get the YEAR and MONTH of the particular dates, say DATE1 and DATE2.


Fun With Date Calculations, What is the correct answer when you add a month to January 31? The most basic way to get a date in iOS is with the Date class: dateComponents.day = 31 dateComponents.month = 2 To convert between date components and dates you need a To get one or more date components from a date:. This problem has been addressed six weeks ago on this site. I give you the link to the post and answers. Subtracting two dates. It is not a trivial problem at all (in particular because of the leap years) and I think that the easiest way to solve it is to go through Julian day numbers and perform substraction.


How to get the differences between two dates in iOS?, We will be using DateFormatter class for formatting the dates. Instances of DateFormatter create string representations of NSDate objects, and  Note: The YEARFRAC function has an optional 3rd argument that controls how days are counted when computing fractional years. The default behavior is to count days between two dates based on a 360-day year, where all 12 months are considered to have 30 days. The YEARFRAC page provides more information.