在 Swift 中,可以使用 NSDateComponents 来帮助 NSDate 保持纳秒精度吗?

Posted

技术标签:

【中文标题】在 Swift 中,可以使用 NSDateComponents 来帮助 NSDate 保持纳秒精度吗?【英文标题】:In Swift, can NSDateComponents be used to help NSDate keep nanosecond precision? 【发布时间】:2015-08-07 16:12:09 【问题描述】:

一些 Playground 代码的快照显示了我尝试以纳秒为单位调整 NSDate,然后通过比较第一个 NSDate 和第二个 NSDate 来尝试获得相同的纳秒值:

鉴于所有关于浮点数和十进制不准确性的内容,我可以看到使用 NSTimeInterval 可能不是这样做的方法。

我认为另一种可能性是使用NSDateComponents。整个过程对我来说真的很困惑。似乎您必须创建一个公历日历对象,然后以某种方式从NSDate 获取纳秒,然后直接调整纳秒并再次将其全部恢复为NSDate。很复杂!

但由于NSCalendar 有一种将纳秒存储为Ints 的内置方法,我想我真的需要澄清它是否可以可靠地用于此目的。

【问题讨论】:

计算两个 NSdate 实例的纳秒差异有什么意义?根据NSDate 上的 Apple 文档,它本质上精确到毫秒。对其进行任何更精确的计算都是无用的。 @utogaria dispatch_time_t 以纳秒为单位工作,因此,如果您要精确使用 Grand Central Dispatch,则需要纳秒 @LeMotJuiced:NSDate 也使用 NSTimeInterval 来存储它的时间值,所以你使用哪个没有任何区别,也不能精确地表示纳秒。您可以使用 NSDateComponents 或表示纳秒的 UInt64。但是,一旦您转换回 NSDate,精度就会丢失。 也许您应该阅读“浮点数和十进制不准确性”。并不是浮点数不准确,只是许多十进制(以 10 为基数)数不能完全表示为二进制(以 2 为基数)浮点数,与 pi 不能表示的方式大致相同精确表示为十进制(以 10 为底)数,但可以精确表示为 pi(以 pi 为底)数。在圆周率基数系统中,圆的周长正好是 2。 @zaph 我指的是问题中的浮点不准确性。这是让我关注 NSDateComponents 的前提。 【参考方案1】:

对于非常精确的时间使用mach_absolute_time()。有关详细信息,请参阅 Apple Q&A1398。

SO answerMartin R 的 Swift 版本

let t1 = mach_absolute_time()
let t2 = mach_absolute_time()

let elapsed = t2 - t1
var timeBaseInfo = mach_timebase_info_data_t()
mach_timebase_info(&timeBaseInfo)
let elapsedNano = elapsed * UInt64(timeBaseInfo.numer) / UInt64(timeBaseInfo.denom);
println(elapsedNano)

Objective-C 版本:

#import <mach/mach_time.h>

mach_timebase_info_data_t info;
mach_timebase_info(&info);

uint64_t start = mach_absolute_time ();
uint64_t end = mach_absolute_time ();
uint64_t elapsed = end - start;

uint64_t nanos = elapsed * info.numer / info.denom;
NSLog(@"elasped: %llu nano seconds", nanos);

CGFloat seconds = (CGFloat)nanos / NSEC_PER_SEC;
NSLog(@"elasped: %0.9f seconds", seconds);

经过:45 纳秒 已用时间:0.000000045 秒

【讨论】:

你说得对,这是一种有用的格式,我在询问是否有另一种方法时犯了一个错误,而没有指定我需要坚持使用 NSDate 作为基础。我已编辑以纠正此问题。在应用程序的上下文中,出于特定原因,我已经在使用 dispatch_time 和 NSDate,并且我不愿意添加带有 janky 转换的第三时间格式。由于 NSCalendar 具有将纳秒存储为 Ints 的内置方式,我想我真的需要澄清它是否可以可靠地用于此目的。刚刚编辑了帖子再次以进一步明确这一点。

以上是关于在 Swift 中,可以使用 NSDateComponents 来帮助 NSDate 保持纳秒精度吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中使用 Apple 地图 - 你必须使用 C 还是 Swift 可以?

在 C/C++ 中使用 swift 库?

我可以在 Swift 中使用啥来代替“for”

你可以在 iOS 应用程序中使用 Package.swift 而不是使用 .xcodeproj 吗?

@distinctUnionOfObjects 可以在 Swift 中使用吗?

在oc代码中使用swift第三方框架