Search code examples
iosswiftnsdatecomponentsformatter

NSDateComponentsFormatter not supported large interval


let date = NSDate()
let future = NSDate.distantFuture()

let f = NSDateComponentsFormatter()
f.unitsStyle = .Full
f.allowedUnits = [.Year, .Month, .Day]

f.stringFromTimeInterval(future.timeIntervalSinceDate(date))

Result is "-57 years, 0 months, 26 days" which is wrong.

I thought this might cause from overflow, so I try smaller number and found that this weird behavior start at 69 years interval

let date = NSDate()

let sixtyEightYears = NSCalendar.currentCalendar().dateByAddingUnit(.Year, value: 68, toDate: date, options: NSCalendarOptions())!
let sixtyNineYears = NSCalendar.currentCalendar().dateByAddingUnit(.Year, value: 69, toDate: date, options: NSCalendarOptions())!

let f = NSDateComponentsFormatter()
f.unitsStyle = .Full
f.allowedUnits = [.Year, .Month, .Day]

future.timeIntervalSinceDate(date)

sixtyEightYears.timeIntervalSinceDate(date) // 2145916800
sixtyNineYears.timeIntervalSinceDate(date) // 2177452800

f.stringFromTimeInterval(sixtyNineYears.timeIntervalSinceDate(date)) // "-67 years, 1 month, 6 days"

Is this the Apple bug, or I did something wrong?


Solution

  • The method timeIntervalSinceDate whose reference date is 1 January 1970 causes the problem.

    1970 + 68 = 2038

    From Wikipedia:

    Year 2038 problem

    The Year 2038 problem is an issue for computing and data storage situations in which time values are stored or calculated as a signed 32-bit integer, and this number is interpreted as the number of seconds since 00:00:00 UTC on 1 January 1970 ("the epoch"). Such implementations cannot encode times after 03:14:07 UTC on 19 January 2038, a problem similar to but not entirely analogous to the "Y2K problem" (also known as the "Millennium Bug"), in which 2-digit values representing the number of years since 1900 could not encode the year 2000 or later. Most 32-bit Unix-like systems store and manipulate time in this "Unix time" format, so the year 2038 problem is sometimes referred to as the "Unix Millennium Bug" by association.

    Full article : Year 2038 problem