为何NSDate经dateWithTimeIntervalSince1970转换后与原日期不等?
为什么NSDate转换前后会不相等?
这事儿其实是浮点数精度在搞鬼!让我给你拆解清楚:
- NSDate的内部存储特性:NSDate实际上是用更高精度的格式存储时间的(比如纳秒级的64位整数),但
timeIntervalSince1970返回的NSTimeInterval本质是Double类型——它的精度有限,无法精确表示所有时间值。 - 转换时的精度丢失:当你把NSDate转成
Double类型的时间戳,再用这个戳转回NSDate时,中间已经丢失了一部分精度。比如原NSDate的时间可能精确到纳秒,但Double只能精确到15-17位十进制数,对于当前10位以上的时间戳来说,小数部分的细微精度会被截断,导致转回的NSDate和原对象存在微小差异。 - isEqualToDate:的严格判断:这个方法是精确比较两个NSDate的时间值,哪怕是纳秒级的差异都会返回NO。所以只要转换后的
newDate和原date有一丁点儿精度损失,就会触发你看到的NSLog(@"Not equal!")。
举个直观的例子:假设原date的内部时间戳是1699999999.123456789(精确到纳秒),转成Double后可能变成1699999999.1234568(Double无法精确存储末尾的小数),再转回去的newDate自然和原date不一样了。
如果要避免这种情况,可以试试这些方案:
- 若不需要纳秒级精度,转换时对时间戳做精度截断,比如保留到毫秒:
interval = round(interval * 1000) / 1000; - 放弃精确比较,改用
timeIntervalSinceDate:判断差异是否在可接受范围内(比如小于0.001秒),而非依赖isEqualToDate:。
内容的提问来源于stack exchange,提问作者StatusReport
相关产品推荐
相关产品推荐

