• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 为什么 NSDate 的 dateWithTimeIntervalSince1970 会修改其输入?

[复制链接]
菜鸟教程小白 发表于 2022-12-12 14:38:57 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在运行以下代码:

for (int i = 0; i < 100; ++i) {
  NSDate *date = [NSDate date];
  NSTimeInterval interval = date.timeIntervalSince1970;
  NSDate *newDate = [NSDate dateWithTimeIntervalSince1970:interval];

  if (![date isEqualToDate:newDate]) {
    NSLog(@"Not equal!");
  }
}

令人惊讶的是,在许多迭代中,日期并不相等。怎么可能?



Best Answer-推荐答案


反汇编dateWithTimeIntervalSince1970:显示调用-initWithIntervalSinceReferenceDate::

CoreFoundation`+[NSDate dateWithTimeIntervalSince1970:]:
    0x10fd39430 <+0>:  pushq  %rbp
    0x10fd39431 <+1>:  movq   %rsp, %rbp
    0x10fd39434 <+4>:  pushq  %rbx
    0x10fd39435 <+5>:  pushq  %rax
    0x10fd39436 <+6>:  movsd  %xmm0, -0x10(%rbp)
    0x10fd3943b <+11>: movq   0x2d8146(%rip), %rsi      ; "alloc"
    0x10fd39442 <+18>: movq   0x29edc7(%rip), %rbx      ; (void *)0x000000010f35e940: objc_msgSend
    0x10fd39449 <+25>: callq  *%rbx
    0x10fd3944b <+27>: movsd  -0x10(%rbp), %xmm0        ; xmm0 = mem[0],zero 
    0x10fd39450 <+32>: addsd  0x1f9d58(%rip), %xmm0     ; _CFLog_os_trace_type_map + 16
    0x10fd39458 <+40>: movq   0x2d9041(%rip), %rsi      ; "initWithTimeIntervalSinceReferenceDate:"
    0x10fd3945f <+47>: movq   %rax, %rdi
    0x10fd39462 <+50>: callq  *%rbx
    0x10fd39464 <+52>: movq   0x2d81b5(%rip), %rsi      ; "autorelease"
    0x10fd3946b <+59>: movq   %rax, %rdi
    0x10fd3946e <+62>: movq   %rbx, %rax
    0x10fd39471 <+65>: addq   $0x8, %rsp
    0x10fd39475 <+69>: popq   %rbx
    0x10fd39476 <+70>: popq   %rbp
    0x10fd39477 <+71>: jmpq   *%rax
    0x10fd39479 <+73>: nopl   (%rax)

此外,初始化程序的输入是 secs - 978307200(或 secs - NSTimeIntervalSince1970),即 1970 年与引用日期之间的时间差。这种计算虽然从 double 中减去整数( double ),但由于舍入误差,可能会更改输入值的分数。例如,这是一个未通过测试的日期:

date: Sun Mar 25 17:54:39 2018 (543682479.8504179716),
newDate: Sun Mar 25 17:54:39 2018 (543682479.8504180908)

由于 log2(543682479.8504179716 + NSTimeIntervalSince1970) ~ 30.5log2(543682479.8504179716) ~ 29.01 需要调整 double 值的指数,尾数需要调整归一化,可能会影响小数值。

解决办法是改用+dateWithTimeIntervalSinceReferenceDate:工厂方法,直接初始化一个NSDate,无需额外计算。

关于ios - 为什么 NSDate 的 dateWithTimeIntervalSince1970 会修改其输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49480305/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap