Apple Watch Series 3中Swift日期处理函数报错,求修复方案
问题描述
以下代码在iOS设备及watchOS模拟器上运行正常:
static func getEventDateTime(startDateTime: Date?) -> String { if let startDateTime = startDateTime { let startTimeInMillis = Int(startDateTime.timeIntervalSince1970 * 1000) let fiveMinutesInMillis = 300000 let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval((startTimeInMillis-fiveMinutesInMillis)/1000)) return convertDateToString(eventStartDateTime) } return "" }
但在Apple Watch Series 3上运行时,会在let startTimeInMillis = Int(startDateTime.timeIntervalSince1970 * 1000)行出现错误:double value cannot be converted to int because the result would be greater than int.max。
修改为以下代码后:
static func getEventDateTime(startDateTime: Date?) -> String { if let startDateTime = startDateTime { let startTimeInMillis = Int64(startDateTime.timeIntervalSince1970 * 1000) let fiveMinutesInMillis = 300000 let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval((Int(startTimeInMillis)-fiveMinutesInMillis)/1000)) return convertDateToString(eventStartDateTime) } return "" }
又在let eventStartDateTime = ...行出现错误:Not enough bits to represent the passed value。需要修改函数使其能在Apple Watch Series 3或watchOS 7上正常运行。
问题原因
Apple Watch Series 3是32位设备,Swift中Int的位数与设备架构绑定——32位设备上Int为32位,最大值仅为2^31-1(约21亿)。而当前时间的timeIntervalSince1970乘以1000后得到的毫秒数约为1.7e12,远超出32位Int的范围,因此第一次转换会触发溢出。
改成Int64后,又强行将64位整数转回32位Int,再次触发溢出,导致第二个错误。
解决方案
方案1:直接用浮点运算(推荐,更简洁)
跳过不必要的整数转换,直接通过Date的API做时间偏移:
static func getEventDateTime(startDateTime: Date?) -> String { guard let startDateTime = startDateTime else { return "" } // 直接减去5分钟(300秒) let eventStartDateTime = startDateTime.addingTimeInterval(-300) return convertDateToString(eventStartDateTime) }
方案2:全程用64位整数处理
如果必须基于毫秒级整数计算,保持使用Int64,避免转回32位Int:
static func getEventDateTime(startDateTime: Date?) -> String { guard let startDateTime = startDateTime else { return "" } let startTimeInMillis = Int64(startDateTime.timeIntervalSince1970 * 1000) let fiveMinutesInMillis: Int64 = 300000 // 用Int64完成差值计算,再转成TimeInterval let adjustedMillis = startTimeInMillis - fiveMinutesInMillis let eventStartDateTime = Date(timeIntervalSince1970: TimeInterval(adjustedMillis) / 1000) return convertDateToString(eventStartDateTime) }
内容的提问来源于stack exchange,提问作者tech_human
相关产品推荐
相关产品推荐

