253

What is the best way to get the current system time milliseconds?

TheNeil
  • 3,321
  • 2
  • 27
  • 52

18 Answers18

330

If you're looking at using this for relative timing (for example for games or animation) I'd rather use CACurrentMediaTime()

double CurrentTime = CACurrentMediaTime();

Which is the recommended way; NSDate draws from the networked synch-clock and will occasionally hiccup when re-synching it against the network.

It returns the current absolute time, in seconds.


If you want only the decimal part (often used when syncing animations),

let ct = CACurrentMediaTime().truncatingRemainder(dividingBy: 1)
Stan James
  • 2,535
  • 1
  • 28
  • 35
Allan Simonsen
  • 3,327
  • 1
  • 15
  • 4
288
[[NSDate date] timeIntervalSince1970];

It returns the number of seconds since epoch as a double. I'm almost sure you can access the milliseconds from the fractional part.

Bhavin Bhadani
  • 22,224
  • 10
  • 78
  • 108
codelogic
  • 71,764
  • 9
  • 59
  • 54
  • 5
    I've been using this method for a while and came to realise it can return an earlier value when you call it after couple of miliseconds (e.g. call it consecutively and you might not end up with an increasing sequence) – Ege Akpinar Jun 30 '14 at 10:27
  • 5
    `[NSDate timeIntervalSinceReferenceDate]` is cheaper. (Though it references a different "epoch" -- if you want 1970 add the constant `NSTimeIntervalSince1970`.) – Hot Licks Sep 13 '14 at 00:53
  • 1
    timeIntervalSince1970 is a instance property and not a static method on NSDate. So one would have to still write NSTimeInterval myInterval = [NSDate date].timeIntervalSince1970 !! – Kris Subramanian Apr 17 '15 at 17:34
  • @KrisSubramanian There's a corresponding `dateWithTimerIntervalSince1970` class method. – Caleb Sep 17 '15 at 17:39
  • 1
    for getting into milliseconds CurrentTime = [[NSDate date] timeIntervalSince1970] * 1000; – Mihir Oza Oct 16 '15 at 07:04
  • 1
    @MihirOza, but multiplying with 1000 won't provide accurate milliseconds. – Satyam Feb 02 '16 at 06:05
  • 2
    @Satyam actually multiplying with 1000 will give you millisecond precision, the TimeInterval returned by `timeIntervalSince1970` is actually a Double with "sub-millisecond precision" according to the docs. – Incinerator Dec 14 '17 at 14:56
100

I benchmarked all the other answers on an iPhone 4S and iPad 3 (release builds). CACurrentMediaTime has the least overhead by a small margin. timeIntervalSince1970 is far slower than the others, probably due to NSDate instantiation overhead, though it may not matter for many use cases.

I'd recommend CACurrentMediaTime if you want the least overhead and don't mind adding the Quartz Framework dependency. Or gettimeofday if portability is a priority for you.

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
devios1
  • 36,899
  • 45
  • 162
  • 260
darrinm
  • 9,117
  • 5
  • 34
  • 34
  • 1
    +1, While this is obviously very informative and helpful I wouldn't exactly call it great engineering work without seeing some source code ;) – Steven Lu Apr 07 '14 at 08:31
  • 3
    Beware of this issue though: http://bendodson.com/weblog/2013/01/29/ca-current-media-time/ This clock apparently stops when the device goes to sleep. – mojuba Jul 25 '15 at 01:30
  • 1
    There is `NSTimeIntervalSince1970` macro which is the fastest. – Ozgur Vatansever Nov 11 '16 at 15:13
  • 1
    @ozgur `NSTimeIntervalSince1970` is a constant describing the seconds between 1970-01-01 and the "reference date" (i.e. 2001-01-01), so it is always equal to 978307200 – YourMJK Mar 02 '20 at 23:11
57

In Swift we can make a function and do as follows

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

var currentTime = getCurrentMillis()

Though its working fine in Swift 3.0 but we can modify and use the Date class instead of NSDate in 3.0

Swift 3.0

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

var currentTime = getCurrentMillis()
Rajan Maheshwari
  • 14,465
  • 6
  • 64
  • 98
33

To get milliseconds for current date.

Swift 4+:

func currentTimeInMilliSeconds()-> Int
    {
        let currentDate = Date()
        let since1970 = currentDate.timeIntervalSince1970
        return Int(since1970 * 1000)
    }
Rajesh Loganathan
  • 11,129
  • 4
  • 78
  • 90
31

So far I found gettimeofday a good solution on iOS (iPad), when you want to perform some interval evaluation (say, framerate, timing of a rendering frame...) :

#include <sys/time.h>
struct timeval time;
gettimeofday(&time, NULL);
long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000);
giampaolo
  • 6,906
  • 5
  • 45
  • 73
Tristan Lorach
  • 471
  • 4
  • 5
  • 2
    I like this too since it's very portable. Note that depending on the OS you might need to use 'long long' instead of a 'long' and likewise cast time.tv_sec to 'long long' before doing the rest of the calculation. – AbePralle Dec 01 '11 at 23:20
  • static unsigned long getMStime(void) { struct timeval time; gettimeofday(&time, NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); } – David H Apr 26 '12 at 13:54
  • Interestingly this works fine on my iPhone 5S and Mac but returns a wrong value on an iPad 3. – Hyndrix Feb 19 '14 at 15:56
  • In order to avoid getting negative numbers I had to cast before the math: int64_t result = ((int64_t)tv.tv_sec * 1000) + ((int64_t)tv.tv_usec / 1000); – jason gilbert Jan 18 '15 at 01:48
  • it return time in -ve – Muhammad Shauket May 13 '16 at 12:22
18

Swift 2

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

Swift 3

let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
quemeful
  • 9,542
  • 4
  • 60
  • 69
10

It may be useful to know about CodeTimestamps, which provide a wrapper around mach-based timing functions. This gives you nanosecond-resolution timing data - 1000000x more precise than milliseconds. Yes, a million times more precise. (The prefixes are milli, micro, nano, each 1000x more precise than the last.) Even if you don't need CodeTimestamps, check out the code (it's open source) to see how they use mach to get the timing data. This would be useful when you need more precision and want a faster method call than the NSDate approach.

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

Tyler
  • 28,498
  • 11
  • 90
  • 106
8
// Timestamp after converting to milliseconds.

NSString * timeInMS = [NSString stringWithFormat:@"%lld", [@(floor([date timeIntervalSince1970] * 1000)) longLongValue]];
Victor Sigler
  • 23,243
  • 14
  • 88
  • 105
Fatima Arshad
  • 350
  • 2
  • 5
6

I needed a NSNumber object containing the exact result of [[NSDate date] timeIntervalSince1970]. Since this function was called many times and I didn't really need to create an NSDate object, performance was not great.

So to get the format that the original function was giving me, try this:

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

Which should give you the exact same result as [[NSDate date] timeIntervalSince1970]

mmackh
  • 3,550
  • 3
  • 35
  • 51
5

CFAbsoluteTimeGetCurrent()

Absolute time is measured in seconds relative to the absolute reference date of Jan 1 2001 00:00:00 GMT. A positive value represents a date after the reference date, a negative value represents a date before it. For example, the absolute time -32940326 is equivalent to December 16th, 1999 at 17:54:34. Repeated calls to this function do not guarantee monotonically increasing results. The system time may decrease due to synchronization with external time references or due to an explicit user change of the clock.

Community
  • 1
  • 1
Inder Kumar Rathore
  • 39,458
  • 17
  • 135
  • 184
5

This is basically the same answer as posted by @TristanLorach, just recoded for 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)
   }
RenniePet
  • 11,420
  • 7
  • 80
  • 106
4

Try this :

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;

In this example, dateWithTimeIntervalSince1970 is used in combination of the formatter @"YYYY-MM-dd HH:mm:ss.SSS" that will return the date with year, month, day and the time with hours, minutes, seconds, and milliseconds. See the example : "2015-12-02 04:43:15.008". I used the NSString to be sure that the format will be has written before.

ΩlostA
  • 2,501
  • 5
  • 27
  • 63
3
let timeInMiliSecDate = Date()
let timeInMiliSec = Int (timeInMiliSecDate.timeIntervalSince1970 * 1000)
print(timeInMiliSec)
lazyTank
  • 1,783
  • 1
  • 8
  • 11
  • Please add some explanation to your code such that others can learn from it - especially if you post an answer to a question that already has a lot of upvoted answers – Nico Haase Apr 25 '19 at 07:38
2
 func currentmicrotimeTimeMillis() -> Int64{
let nowDoublevaluseis = NSDate().timeIntervalSince1970
return Int64(nowDoublevaluseis*1000)

}

Softlabsindia
  • 791
  • 6
  • 11
1

This is what I used for Swift

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

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

used this site to verify accuracy http://currentmillis.com/

DG7
  • 161
  • 3
  • 15
1
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];
PANKAJ VERMA
  • 3,450
  • 1
  • 16
  • 15
0

[NSDate timeIntervalSinceReferenceDate] is another option, if you don't want to include the Quartz framework. It returns a double, representing seconds.

Chris
  • 39,719
  • 45
  • 189
  • 235