iPhone: ¿Cómo obtener milisegundos actuales?


Respuestas:


273
[[NSDate date] timeIntervalSince1970];

Devuelve el número de segundos desde la época como un doble. Estoy casi seguro de que puede acceder a los milisegundos desde la parte fraccional.


29
no mata a nadie escribirlo así: NSTimeInterval myInterval = NSDate.timeIntervalSince1970; // todos esos corchetes son realmente anticuados si me preguntas.
Pizzaiola Gorgonzola

11
'esos corchetes' son una versión más nueva de la sintaxis según stackoverflow.com/q/11474284/209828
Matthew

119
"esos corchetes" son objetivos-c. Si desea desarrollar para iOS, probablemente debería sentirse cómodo con ellos.
Ampers4 de

55
He estado usando este método durante un tiempo y me di cuenta de que puede devolver un valor anterior cuando lo llamas después de un par de milisegundos (por ejemplo, llámalo consecutivamente y es posible que no termines con una secuencia creciente)
Ege Akpinar

55
[NSDate timeIntervalSinceReferenceDate]es más barato. (Aunque hace referencia a una "época" diferente, si desea 1970 agregue la constante NSTimeIntervalSince1970.)
Hot Licks

311

Si está buscando usar esto para el tiempo relativo (por ejemplo, para juegos o animación) prefiero usar CACurrentMediaTime ()

double CurrentTime = CACurrentMediaTime();

Cuál es la forma recomendada; NSDatese basa en el reloj sincronizado en red y ocasionalmente fallará cuando se vuelva a sincronizar con la red.

Devuelve el tiempo absoluto actual, en segundos.


Si solo desea la parte decimal (a menudo utilizada al sincronizar animaciones),

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

77
Pero parece tomar el doble del tiempo necesario para [[fecha NSD] timeIntervalSince1970]. Medí 0.065ms vs. 0.033ms en 15000 llamadas.
Kay

1
Tenga en cuenta que deberá incluir Quartz Framework y #import <Quartz / CABase.h> para realizar esta llamada.
BadPirate

8
Whoops - eso es importación #import <QuartzCore / CAAnimation.h>
BadPirate

66
Para aquellos nuevos en Xcode (como yo) "incluir Quartz Framework" significa agregarlo al conjunto de bibliotecas en "Link Binary With Libraries".
Gabe Johnson

3
Si alguien está buscando esto en relación con SpriteKit, la 'hora actual' en el método de actualización de SKScene es de hecho CACurrentMediaTime ();
Anthony Mattox

92

Comparé todas las otras respuestas en un iPhone 4S y iPad 3 (versiones de lanzamiento). CACurrentMediaTimetiene la menor sobrecarga por un pequeño margen. timeIntervalSince1970es mucho más lento que los demás, probablemente debido a la NSDatesobrecarga de instanciación, aunque puede no importar para muchos casos de uso.

Recomiendo CACurrentMediaTimesi desea la menor sobrecarga y no le importa agregar la dependencia de Quartz Framework. O gettimeofdaysi la portabilidad es una prioridad para usted.

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, aunque esto es obviamente muy informativo y útil, no lo llamaría exactamente un gran trabajo de ingeniería sin ver algún código fuente;)
Steven Lu

2
Sin embargo, tenga cuidado con este problema: bendodson.com/weblog/2013/01/29/ca-current-media-time Este reloj aparentemente se detiene cuando el dispositivo se pone en suspensión.
mojuba

1
Hay NSTimeIntervalSince1970macro que es el más rápido.
ozgur

@ozgur NSTimeIntervalSince1970es una constante que describe los segundos entre 1970-01-01 y la "fecha de referencia" (es decir, 2001-01-01), por lo que siempre es igual a 978307200
YourMJK

53

En Swift podemos hacer una función y hacer lo siguiente

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

var currentTime = getCurrentMillis()

Aunque funciona bien en Swift 3.0 , podemos modificar y usar la Dateclase en lugar de NSDateen 3.0

Swift 3.0

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

var currentTime = getCurrentMillis()

30

Hasta ahora encontré gettimeofdayuna buena solución en iOS (iPad), cuando desea realizar alguna evaluación de intervalo (por ejemplo, velocidad de cuadros, tiempo de un cuadro de renderizado ...):

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

2
Esto también me gusta porque es muy portátil. Tenga en cuenta que, dependiendo del sistema operativo, es posible que necesite usar 'long long' en lugar de 'long' y, de la misma manera, lanzar time.tv_sec a 'long long' antes de realizar el resto del cálculo.
AbePralle

estático sin signo largo getMStime (void) {estructura timeval time; gettimeofday (& time, NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); }
David H

Curiosamente, esto funciona bien en mi iPhone 5S y Mac, pero devuelve un valor incorrecto en un iPad 3.
Hyndrix

Para evitar obtener números negativos, tuve que emitir antes de las matemáticas: int64_t result = ((int64_t) tv.tv_sec * 1000) + ((int64_t) tv.tv_usec / 1000);
Jason Gilbert

es tiempo de regreso en -ve
Shauket Sheikh

23

Para obtener milisegundos para la fecha actual.

Swift 4+:

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

18

Swift 2

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

Swift 3

let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds

2
TimeIntervalaka Doubleno tiene propiedad de milisegundos. Date().timeIntervalSince1970 * 1000
Leo Dabus

10

Puede ser útil saber sobre CodeTimestamps, que proporcionan una envoltura alrededor de las funciones de temporización basadas en mach. Esto le brinda datos de tiempo de resolución en nanosegundos: 1000000x más precisos que milisegundos. Sí, un millón de veces más preciso. (Los prefijos son mili, micro, nano, cada uno 1000 veces más preciso que el anterior). Incluso si no necesita CodeTimestamps, consulte el código (es de código abierto) para ver cómo usan mach para obtener los datos de sincronización. Esto sería útil cuando necesite más precisión y desee una llamada a un método más rápido que el enfoque NSDate.

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


Y probablemente necesitarás un -fno-objc-arcsi estás usando ARC :)
Dan Rosenstark


3
El código fuente vinculado desde la página está aquí: github.com/tylerneylon/moriarty
Tomas Andrle

8
// Timestamp after converting to milliseconds.

NSString * timeInMS = [NSString stringWithFormat:@"%lld", [@(floor([date timeIntervalSince1970] * 1000)) longLongValue]];

6

Necesitaba un NSNumberobjeto que contenga el resultado exacto de [[NSDate date] timeIntervalSince1970]. Dado que esta función se llamó muchas veces y realmente no necesitaba crear unNSDate objeto, el rendimiento no fue excelente.

Entonces, para obtener el formato que me estaba dando la función original, intente esto:

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

Lo que debería darte exactamente el mismo resultado que [[NSDate date] timeIntervalSince1970]


4

CFAbsoluteTimeGetCurrent ()

El tiempo absoluto se mide en segundos con respecto a la fecha de referencia absoluta del 1 de enero de 2001 00:00:00 GMT. Un valor positivo representa una fecha posterior a la fecha de referencia, un valor negativo representa una fecha anterior. Por ejemplo, el tiempo absoluto -32940326 es equivalente al 16 de diciembre de 1999 a las 17:54:34. Las llamadas repetidas a esta función no garantizan resultados monotónicamente crecientes. La hora del sistema puede disminuir debido a la sincronización con referencias de hora externas o debido a un cambio explícito del reloj del usuario.


4

Prueba esto :

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;

En este ejemplo, dateWithTimeIntervalSince1970 se usa en combinación con el formateador @ "AAAA-MM-dd HH: mm: ss.SSS" que devolverá la fecha con año, mes, día y hora con horas, minutos, segundos y milisegundos . Vea el ejemplo: "2015-12-02 04: 43: 15.008". Utilicé NSString para asegurarme de que el formato se haya escrito antes.


4

Esta es básicamente la misma respuesta publicada por @TristanLorach, recién recodificada para 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

Esto es lo que usé para Swift

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

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

usó este sitio para verificar la precisión http://currentmillis.com/


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

Agregue alguna explicación a su código para que otros puedan aprender de él, especialmente si publica una respuesta a una pregunta que ya tiene muchas respuestas votadas
Nico Haase

0

[NSDate timeIntervalSinceReferenceDate]es otra opción, si no desea incluir el marco de Quartz. Devuelve un doble, que representa segundos.


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];
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.