Calendar date incorrect for some ISO8601 durations

When testing some code which parses an Iso8601 duration string and generates a TimeInterval, I came across some interesting behavior, which I take to be bug, but I may have missed some setup which would set things right. The short of it... Given the Iso8601 duration string, e.g., "P10675199DT2H48M5.4775" which has been parsed into DateComponents, use Calendar.current.date(byAdding:to:) to get a future date. When futureDate.timeIntervalSince(currentDate) is calculated, the interval returned MAY be different from the result of a manual calculation - off by one hour, or incorrect fractional seconds. The inital test was run using a number-of-days value for ~30k yrs. However, using other, smaller values can produce errors as well. Copy/Paste the following code into a playground to check me. Anyone know what might be happenging?


import Cocoa

var str = "Hello, playground"


// Given the Iso8601 duration string "P10675199DT2H48M5.4775"  (Yeah, made up for testing.  Who really cares about a duration of ~30k yrs. Yikes!)
let nanoSecs = Int(0.4775 * Double(NSEC_PER_SEC))
let components = DateComponents(calendar: nil, timeZone: nil, era: nil, year: nil, month: nil, day: 10675199, hour: 2, minute: 48, second: 5, nanosecond: nanoSecs, weekday: nil, weekdayOrdinal: nil, quarter: nil, weekOfMonth: nil, weekOfYear: nil, yearForWeekOfYear: nil)
//let components = DateComponents(calendar: nil, timeZone: nil, era: nil, year: nil, month: nil, day: 20*365, hour: 2, minute: 48, second: 5, nanosecond: nanoSecs, weekday: nil, weekdayOrdinal: nil, quarter: nil, weekOfMonth: nil, weekOfYear: nil, yearForWeekOfYear: nil)
let currentDate = Date()
var calendarDuration: TimeInterval = 0
if let futureDate = Calendar.current.date(byAdding: components, to: currentDate) {
    let futureDateComponents = Calendar.current.dateComponents([Calendar.Component.day, Calendar.Component.month, Calendar.Component.year], from: futureDate)
    print(futureDateComponents)
    calendarDuration = futureDate.timeIntervalSince(currentDate)
}

// Compare against a manual calculation
let secondsPerDay: TimeInterval = 86400
let secondsPerHour: TimeInterval = 3600
let secondsPerMinute: TimeInterval = 60

let calcDuration = (10675199 * secondsPerDay) + (2 * secondsPerHour) + (48 * secondsPerMinute) + 5.4775
//let calcDuration = ( 20*365 * secondsPerDay) + (2 * secondsPerHour) + (48 * secondsPerMinute) + 5.4775

print(calendarDuration) // 922337207285.4775
print(calcDuration)     // 922337203685.4775
print(calendarDuration - calcDuration) // = 3600.0  Off by 1 hour!!

// Interestingly, for some values of the number of days (e.g., 20*365, but not 30*365) the fractinal seconds value starts to go heywire.