问题
Crashing for large interval between dates while trying to use date components in swift (for example dates used is 16 August 1979 to 11 may 2053) The code for date components is
ComponentsforDetail = (Calendar.current as NSCalendar).components([.second], from: FromDateValue!, to: ToValueDate!, options: [])
Using breakpoints i found out the thread_exc happens in an assembly line code
libswiftFoundation.dylib`static Foundation.DateComponents._unconditionallyBridgeFromObjectiveC (Swift.Optional<__ObjC.NSDateComponents>) -> Foundation.DateComponents:
0x16cf280 <+0>: push {r4, r5, r7, lr}
0x16cf284 <+4>: add r7, sp, #8
0x16cf288 <+8>: sub sp, sp, #4
0x16cf28c <+12>: mov r4, r0
0x16cf290 <+16>: mov r0, #0
0x16cf294 <+20>: str r0, [sp]
0x16cf298 <+24>: cmp r4, #0
0x16cf29c <+28>: beq 0x16cf2dc ; <+92>
0x16cf2a0 <+32>: mov r0, r4
0x16cf2a4 <+36>: bl 0x17a42e8 ; symbol stub for: objc_retain
0x16cf2a8 <+40>: mov r1, sp
0x16cf2ac <+44>: mov r0, r4
0x16cf2b0 <+48>: bl 0x174ed80 ; function signature specialization <Arg[0] = Owned To Guaranteed, Arg[2] = Dead> of static Foundation.DateComponents._conditionallyBridgeFromObjectiveC (__ObjC.NSDateComponents, result : inout Swift.Optional<Foundation.DateComponents>) -> Swift.Bool
0x16cf2b4 <+52>: mov r0, r4
0x16cf2b8 <+56>: bl 0x17a42d8 ; symbol stub for: objc_release
0x16cf2bc <+60>: ldr r5, [sp]
0x16cf2c0 <+64>: cmp r5, #0
0x16cf2c4 <+68>: beq 0x16cf2e0 ; <+96>
0x16cf2c8 <+72>: mov r0, r4
0x16cf2cc <+76>: bl 0x17a42d8 ; symbol stub for: objc_release
0x16cf2d0 <+80>: mov r0, r5
0x16cf2d4 <+84>: sub sp, r7, #8
0x16cf2d8 <+88>: pop {r4, r5, r7, pc}
-> 0x16cf2dc <+92>: trap (Here is the breakpoint exception Happening)
0x16cf2e0 <+96>: trap
I think this is an issue with integer format because anything greater than 68 years is causing this crash in Datecomponents for seconds I've used Playground to identify the issue the code used in playground is
import UIKit
var str = "Hello, playground"
let dateString1 = "1979-11-28 07:57:20 +0000"
let dateString2 = "2048-11-29 10:59:00 +0000"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let date1 = formatter.date(from: dateString1)!
let date2 = formatter.date(from: dateString2)!
let calendar = NSCalendar.current
let components1 = (Calendar.current as NSCalendar).components([NSCalendar.Unit.minute], from: date1, to: date2, options: NSCalendar.Options.init(rawValue: 0))
let components2 = (Calendar.current as NSCalendar).components([.second], from: date1, to: date2, options: [])
Anything for date2 greater than year 2047 will result this error
回答1:
The problem seems to happen when the dateComponents
of Calendar
is used to get the number of seconds between two dates and the resulting number of seconds is too large to fit in a signed 32-bit integer (2^31).
An alternate solution is to use Date timeIntervalSince
to get the number of seconds between two dates.
Your updated code becomes:
let dateString1 = "1979-11-28 07:57:20 +0000"
let dateString2 = "2048-11-29 10:59:00 +0000"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let date1 = formatter.date(from: dateString1)!
let date2 = formatter.date(from: dateString2)!
let seconds = date2.timeIntervalSince(date1)
let components1 = Calendar.current.dateComponents([ .minute ], from: date1, to: date2)
let minutes = components1.minute
This gives 2177636500
for seconds and 36293941
for minutes.
来源:https://stackoverflow.com/questions/43876695/crash-while-using-datecomponents-having-larger-differences