iPhone:如何获取当前毫秒数?


Answers:


273
[[NSDate date] timeIntervalSince1970];

它返回自纪元以来的秒数(双精度)。我几乎确定您可以从小数部分访问毫秒。


29
它不会杀死任何人这样写:NSTimeInterval myInterval = NSDate.timeIntervalSince1970; //如果您问我,所有这些括号实际上都是过时的。
Pizzaiola Gorgonzola


119
“那些括号”是目标-c。如果您想为iOS开发,可能应该对它们感到满意。
Ampers4nd

5
我使用这种方法已经有一段时间了,我意识到当您在几个毫秒后调用它时,它可以返回一个更早的值(例如,连续调用它,并且您可能不会以递增的顺序结束)
Ege Akpinar

5
[NSDate timeIntervalSinceReferenceDate]比较便宜 (尽管它引用了一个不同的“时期”-如果您想在1970年添加常量NSTimeIntervalSince1970。)
Hot Licks

311

如果您打算将其用于相对时间(例如游戏或动画),则宁愿使用CACurrentMediaTime()

double CurrentTime = CACurrentMediaTime();

推荐的方法; NSDate从联网的同步时钟中提取数据,并在与网络重新同步时偶尔会打h。

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


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

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

7
但这似乎需要[[NSDate date] timeIntervalSince1970]所需时间的两倍。我在15000次通话中测得0.065ms与0.033ms。

1
注意,您需要包括Quartz Framework和#import <Quartz / CABase.h>才能进行此调用。
BadPirate

8
糟糕-那就是import #import <QuartzCore / CAAnimation.h>
BadPirate

6
对于那些像我这样的Xcode新手,“ include Quartz Framework”意味着将其添加到“ Link Binary With Libraries”中的库集中。
·约翰逊

3
如果有人在寻找与SpriteKit相关的内容,则SKScene的update方法中的“当前时间”确实是CACurrentMediaTime();
Anthony Mattox

92

我在iPhone 4S和iPad 3(发布版本)上对所有其他答案进行了基准测试。CACurrentMediaTime开销最小,利润也很少。虽然实例化开销可能并不重要,但它timeIntervalSince1970却比其他NSDate实例慢得多。

我建议CACurrentMediaTime您是否需要最少的开销,并且不介意添加Quartz Framework依赖项。或者,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

1
+1,虽然这显然非常有用,但我在没有看到一些源代码的情况下就不会称其为出色的工程工作;)
Steven Lu

2
不过请当心此问题:bentodson.com/weblog/2013/01/29/ca-current-media-time设备进入睡眠状态时,该时钟显然停止了。
mojuba

1
NSTimeIntervalSince1970最快的宏。
ozgur

@ozgur NSTimeIntervalSince1970是一个常量,描述了1970-01-01和“参考日期”之间的秒数(即2001-01-01),因此它始终等于978307200
YourMJK

53

在Swift中,我们可以创建一个函数并执行以下操作

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

var currentTime = getCurrentMillis()

尽管它在Swift 3.0中可以正常工作,但是我们可以修改和使用Date该类,而不是NSDate3.0中

斯威夫特3.0

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

var currentTime = getCurrentMillis()

30

到目前为止gettimeofday,当您要执行一些间隔评估(例如,帧速率,渲染帧的时间...)时,我在iOS(iPad)上找到了一个不错的解决方案:

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

2
我也喜欢它,因为它非常便携。请注意,根据操作系统的不同,在执行其余计算之前,可能需要使用“ long long”而不是“ long”,并且同样将time.tv_sec转换为“ long long”。
2011年

静态无符号长getMStime(void){结构timeval时间;gettimeofday(&time,NULL); 返回(time.tv_sec * 1000)+(time.tv_usec / 1000); }
David H

有趣的是,这在我的iPhone 5S和Mac上正常运行,但在iPad 3上返回错误值
。– Hyndrix 2014年

为了避免得到负数,我必须在数学运算之前进行强制转换:int64_t result =((int64_t)tv.tv_sec * 1000)+((int64_t)tv.tv_usec / 1000);
杰森·吉尔伯特

它返回的时间为-ve
谢克谢赫(Shauket Sheikh)

23

获取当前日期的毫秒数。

迅捷4+:

func currentTimeInMilliSeconds()-> Int
    {
        let currentDate = Date()
        let since1970 = currentDate.timeIntervalSince1970
        return Int(since1970 * 1000)
    }

18

迅捷2

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

迅捷3

let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds

2
TimeIntervalaka Double没有毫秒属性。Date().timeIntervalSince1970 * 1000
Leo Dabus

10

了解CodeTimestamps可能很有用,它为基于mach的计时功能提供了包装。这为您提供了纳秒级精度的计时数据-比毫秒精度高1000000x。是的,精确度提高了一百万倍。(前缀为milli,micro,nano,每个精度都比最后一个精度高1000倍。)即使您不需要CodeTimestamps,也请查看代码(它是开放源代码),以查看它们如何使用mach来获取计时数据。当您需要更高的精度并且想要比NSDate方法更快的方法调用时,这将很有用。

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


-fno-objc-arc如果您使用的是ARC,则可能需要一个:)
Dan Rosenstark 2011年


3
从页面链接的源代码在这里:github.com/tylerneylon/moriarty
Tomas Andrle 2014年


6

我需要一个NSNumber包含确切结果的对象[[NSDate date] timeIntervalSince1970]。由于此函数已被调用过多次,因此我并不需要创建一个NSDate对象,因此性能并不理想。

因此,要获取原始功能给我的格式,请尝试以下操作:

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

哪个应该给您与完全相同的结果 [[NSDate date] timeIntervalSince1970]


4

CFAbsoluteTimeGetCurrent()

绝对时间以秒为单位,相对于格林尼治标准时间2001年1月1日00:00:00的绝对参考日期。正值表示参考日期之后的日期,负值表示参考日期之前的日期。例如,绝对时间-32940326等于1999年12月16日17:54:34。重复调用此函数不能保证单调递增的结果。系统时间可能由于与外部时间参考同步或由于用户明确更改时钟而减少。


4

试试这个 :

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来确保该格式已被写入。


4

这基本上与@TristanLorach发布的答案相同,只是为Swift 3重新编码了:

   /// Method to get Unix-style time (Java variant), i.e., 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)
   }

2
 func currentmicrotimeTimeMillis() -> Int64{
let nowDoublevaluseis = NSDate().timeIntervalSince1970
return Int64(nowDoublevaluseis*1000)

}


1

这就是我用过的Swift

var date = NSDate()
let currentTime = Int64(date.timeIntervalSince1970 * 1000)

print("Time in milliseconds is \(currentTime)")

使用此网站来验证准确性http://currentmillis.com/


1
let timeInMiliSecDate = Date()
let timeInMiliSec = Int (timeInMiliSecDate.timeIntervalSince1970 * 1000)
print(timeInMiliSec)

请在您的代码中添加一些解释,以便其他人可以从中学习—特别是如果您发布对已经有很多推荐答案的问题的答案
Nico Haase

0

[NSDate timeIntervalSinceReferenceDate]如果您不想包括Quartz框架,则是另一种选择。它返回一个代表秒的双精度数。


0
NSTimeInterval time = ([[NSDate date] timeIntervalSince1970]); //double
long digits = (long)time; //first 10 digits        
int decimalDigits = (int)(fmod(time, 1) * 1000); //3 missing digits
/*** long ***/
long timestamp = (digits * 1000) + decimalDigits;
/*** string ***/
NSString *timestampString = [NSString stringWithFormat:@"%ld%03d",digits ,decimalDigits];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.