iPhone:如何获得当前毫秒?

获得当前系统时间毫秒的最佳方式是什么?

[[NSDate date] timeIntervalSince1970]; 

它返回自epoch以秒为单位的秒数。 我几乎可以肯定,你可以从小数部分访问毫秒。

如果你正在使用这个相对时间(例如游戏或animation),我宁愿使用CACurrentMediaTime()

 double CurrentTime = CACurrentMediaTime(); 

推荐的方式是什么? NSDate从联网的同步时钟吸取,偶尔会在与networking重新同步时发生打嗝。

它返回当前绝对时间,以秒为单位。


如果您需要小数部分(通常在同步animation时使用),

 let ct = CACurrentMediaTime().truncatingRemainder(dividingBy: 1) 

我在iPhone 4S和iPad 3(发布版本)上testing了所有其他答案。 CACurrentMediaTime具有最小的开销。 timeIntervalSince1970比其他的慢得多,可能是由于NSDate实例化开销,尽pipe对于许多用例来说可能并不重要。

我build议CACurrentMediaTime如果你想最小的开销,不介意添加Quartz框架的依赖。 或者如果可移植性是您的首要任务,那么gettimeofday

iPhone 4S

 CACurrentMediaTime: 1.33 µs/call gettimeofday: 1.38 µs/call [NSDate timeIntervalSinceReferenceDate]: 1.45 µs/call CFAbsoluteTimeGetCurrent: 1.48 µs/call [[NSDate date] timeIntervalSince1970]: 4.93 µs/call 

iPad 3

 CACurrentMediaTime: 1.25 µs/call gettimeofday: 1.33 µs/call CFAbsoluteTimeGetCurrent: 1.34 µs/call [NSDate timeIntervalSinceReferenceDate]: 1.37 µs/call [[NSDate date] timeIntervalSince1970]: 3.47 µs/call 

在Swift中,我们可以做一个函数,做如下

 func getCurrentMillis()->Int64{ return Int64(NSDate().timeIntervalSince1970 * 1000) } var currentTime = getCurrentMillis() 

虽然它在Swift 3.0中工作正常,但我们可以在3.0中修改和使用Date类而不是NSDate

Swift 3.0

 func getCurrentMillis()->Int64 { return Int64(Date().timeIntervalSince1970 * 1000) } var currentTime = getCurrentMillis() 

到目前为止,我发现gettimeofday是iOS(iPad)上的一个很好的解决scheme,当你想要执行一些时间间隔评估(比如,帧率,渲染帧的时间…):

 #include <sys/time.h> struct timeval time; gettimeofday(&time, NULL); long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000); 

了解CodeTimestamps可能是有用的CodeTimestamps提供了基于mach的定时function的封装。 这给你纳秒分辨率的时间数据 – 比毫秒精确1000000倍。 是的,精确到一百万倍。 (前缀是毫米,微米,纳米,比上一代精度要高1000倍)。即使你不需要CodeTimestamps,也可以看看代码(它是开源的),看看它们如何使用mach来获取计时数据。 如果您需要更高的精度并希望比NSDate方法更快的方法调用,这将会非常有用。

http://eng.pulse.me/line-by-line-speed-analysis-for-ios-apps/

Swift 2

 let seconds = NSDate().timeIntervalSince1970 let milliseconds = seconds * 1000.0 

Swift 3

 let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds 
 // Timestamp after converting to milliseconds. NSString * timeInMS = [NSString stringWithFormat:@"%lld", [@(floor([date timeIntervalSince1970] * 1000)) longLongValue]]; 

我需要一个包含[[NSDate date] timeIntervalSince1970]的确切结果的NSNumber对象。 由于这个函数被调用了很多次,我并不需要创build一个NSDate对象,所以性能并不好。

所以要得到原始函数给我的格式,试试这个:

 #include <sys/time.h> struct timeval tv; gettimeofday(&tv,NULL); double perciseTimeStamp = tv.tv_sec + tv.tv_usec * 0.000001; 

这应该给你完全相同的结果[[NSDate date] timeIntervalSince1970]

CFAbsoluteTimeGetCurrent()

绝对时间以相对于2001年1月1日00:00:00 GMT绝对参考date的秒数来测量。 正值表示参考date之后的date,负值表示之前的date。 例如,绝对时间-32940326相当于1999年12月16日17:54:34。 重复调用此函数并不能保证单调递增的结果。 系统时间可能由于与外部时间参考同步或由于明确的时钟用户更改而降低。

尝试这个 :

 NSDate * timestamp = [NSDate dateWithTimeIntervalSince1970:[[NSDate date] timeIntervalSince1970]]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"YYYY-MM-dd HH:mm:ss.SSS"]; NSString *newDateString = [dateFormatter stringFromDate:timestamp]; timestamp = (NSDate*)newDateString; 

在这个例子中,dateWithTimeIntervalSince1970与格式化程序@“YYYY-MM-dd HH:mm:ss.SSS”结合使用,它将返回年,月,日的时间以及小时,分钟,秒和毫秒的时间。 看例子:“2015-12-02 04:43:15.008”。 我使用NSString来确保格式将被写入之前。

这是我用于Swift的

 var date = NSDate() let currentTime = Int64(date.timeIntervalSince1970 * 1000) print("Time in milliseconds is \(currentTime)") 

用这个网站来validation准确性http://currentmillis.com/

这与@TristanLorach发布的答案基本相同,只是logging了Swift 3:

  /// Method to get Unix-style time (Java variant), ie, time since 1970 in milliseconds. This /// copied from here: http://stackoverflow.com/a/24655601/253938 and here: /// http://stackoverflow.com/a/7885923/253938 /// (This should give good performance according to this: /// http://stackoverflow.com/a/12020300/253938 ) /// /// Note that it is possible that multiple calls to this method and computing the difference may /// occasionally give problematic results, like an apparently negative interval or a major jump /// forward in time. This is because system time occasionally gets updated due to synchronization /// with a time source on the network (maybe "leap second"), or user setting the clock. public static func currentTimeMillis() -> Int64 { var darwinTime : timeval = timeval(tv_sec: 0, tv_usec: 0) gettimeofday(&darwinTime, nil) return (Int64(darwinTime.tv_sec) * 1000) + Int64(darwinTime.tv_usec / 1000) } 

[NSDate timeIntervalSinceReferenceDate]是另一个选项,如果你不想包含Quartz框架的话。 它返回一个double,代表秒。

使用这种方法:

 [[NSDate date] timeIntervalSince1970]*1000; 

它像Java中的System.currentTimeMillis()一样;