Search code examples
iosiphoneswiftdatedate-manipulation

Crash on simple Date() manipulations in Swift


I got more and more crash-reports from apple (all on iPhone 5, iOS 10.3.3) on the following lines of code:

    let date = NSDate()
    var dateComponents = DateComponents()
    dateComponents.hour = -6
    let calculatedDate = NSCalendar.current.date(byAdding: dateComponents, to: date as Date)

    let selectStatement = "SELECT nr from info where date > \(UInt((calculatedDate!.timeIntervalSince1970)) * 1000);"

The crash-report states the last line as the problem-line. So it seems, that calculatedDate is not instantiated.

In a former version a crash even occured in the first line (iPhone 5, iOS 10.3.2)

I by myself can't reproduce these crashes on an iPhone 6s.

Any suggestions what could go wrong in these statements?


Solution

  • The problem is that the iPhone 5 is a 32bit device and you are getting an Integer overflow. See the error here when explicitly casting the result into Int32.

    Use UInt64 instead of UInt to tackle the overflow issue on 32bit devices if you definitely need an integer value for your select statement.

    Unrelated to the issue, but mixing Foundation types with native Swift types is discouraged when you can just use native Swift types (Date and Calendar).

    Code showing the issue explicitly:

    import Foundation
    
    let date = Date()
    var dateComponents = DateComponents()
    dateComponents.hour = -6
    let calculatedDate = Calendar.current.date(byAdding: dateComponents, to: date)
    let selectStatement = "SELECT nr from info where date > \(UInt((calculatedDate!.timeIntervalSince1970)) * 1000);"
    print(selectStatement) //prints 1504234558000
    print(Int32(1504234558000))
    

    ERROR at line 9, col 7: integer overflows when converted from 'Int' to 'Int32' print(Int32(1504234558000))