iPhone: Como obter milissegundos atuais?


Respostas:


273
[[NSDate date] timeIntervalSince1970];

Retorna o número de segundos desde a época como um dobro. Tenho quase certeza de que você pode acessar os milissegundos da parte fracionária.


29
não mata ninguém escrever assim: NSTimeInterval myInterval = NSDate.timeIntervalSince1970; // todos esses colchetes são realmente antiquados, se você me perguntar.
Pizzaiola Gorgonzola 02/10

11
'esses colchetes' são uma versão mais recente da sintaxe de acordo com stackoverflow.com/q/11474284/209828
Matthew

119
"esses colchetes" são objetivos-c. Se você deseja desenvolver para iOS, provavelmente deve se sentir confortável com eles.
precisa saber é o seguinte

5
Eu uso esse método há algum tempo e percebi que ele pode retornar um valor anterior quando você o chama depois de alguns milissegundos (por exemplo, chamá-lo consecutivamente e você pode não acabar com uma sequência crescente)
Ege Akpinar

5
[NSDate timeIntervalSinceReferenceDate]é mais barato. (Embora ele faz referência a uma "época" diferente - se você quiser 1970 adicionar a constante NSTimeIntervalSince1970.)
Hot Licks

311

Se você estiver usando isso para um tempo relativo (por exemplo, para jogos ou animação), prefiro usar CACurrentMediaTime ()

double CurrentTime = CACurrentMediaTime();

Qual é o caminho recomendado; NSDateextrai do relógio de sincronização em rede e ocasionalmente soluça ao sincronizá-lo novamente com a rede.

Retorna o tempo absoluto atual, em segundos.


Se você deseja apenas a parte decimal (geralmente usada ao sincronizar animações),

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

7
Mas parece levar o dobro do tempo necessário para [[NSDate date] timeIntervalSince1970]. Eu medi 0,065ms vs. 0,033ms em 15000 chamadas.
Kay

1
Observe que você precisará incluir o Quartz Framework e #import <Quartz / CABase.h> para fazer esta chamada.
BadPirate

8
Oops, isso é # importação # QuartzCore / CAAnimation.h>
BadPirate

6
Para quem é novo no Xcode (como eu), "inclui o Quartz Framework" significa adicioná-lo ao conjunto de bibliotecas em "Vincular Binário com Bibliotecas".
Gabe Johnson

3
Se alguém está procurando por isso em relação ao SpriteKit, o 'horário atual' no método de atualização do SKScene é de fato o CACurrentMediaTime ();
Anthony Mattox

92

Comparei todas as outras respostas em um iPhone 4S e iPad 3 (compilações de versão). CACurrentMediaTimetem o mínimo de sobrecarga por uma pequena margem. timeIntervalSince1970é muito mais lento que os outros, provavelmente devido à NSDatesobrecarga da instanciação, embora possa não ser importante para muitos casos de uso.

Eu recomendo CACurrentMediaTimese você deseja o mínimo de sobrecarga e não se importa de adicionar a dependência do Quartz Framework. Ou gettimeofdayse a portabilidade é uma prioridade para você.

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, Enquanto isso é, obviamente, muito informativo e útil Eu não chamaria exatamente que grande obra de engenharia sem ver algum código fonte;)
Steven Lu

2
Porém, tenha cuidado com esse problema: bendodson.com/weblog/2013/01/29/ca-current-media-time Esse relógio aparentemente para quando o dispositivo entra no modo de suspensão.
Mojuba

1
NSTimeIntervalSince1970macro que é o mais rápido.
ozgur

@ozgur NSTimeIntervalSince1970é uma constante que descreve os segundos entre 01-01-2009 e a "data de referência" (ou seja, 01-01-2001), portanto é sempre igual a 978307200
YourMJK

53

Em Swift, podemos criar uma função e fazer o seguinte

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

var currentTime = getCurrentMillis()

Apesar de seu bom trabalho em Swift 3.0 , mas podemos modificar e usar a Dateclasse em vez de NSDateem 3.0

Swift 3.0

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

var currentTime = getCurrentMillis()

30

Até agora, encontrei gettimeofdayuma boa solução no iOS (iPad), quando você deseja realizar alguma avaliação de intervalo (por exemplo, taxa de quadros, tempo de um quadro de renderização ...):

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

2
Eu também gosto disso, pois é muito portátil. Observe que, dependendo do sistema operacional, você pode precisar usar 'long long' em vez de 'long' e da mesma forma converter time.tv_sec para 'long long' antes de fazer o restante do cálculo.
AbePralle

estático não assinado long getMStime (void) {struct timeval time; gettimeofday (& time, NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); }
David H

Curiosamente esta multa funciona no meu iPhone 5S e Mac, mas retorna um valor errado em um iPad 3.
Hyndrix

Para evitar números negativos, tive que converter antes da matemática: int64_t result = ((int64_t) tv.tv_sec * 1000) + ((int64_t) tv.tv_usec / 1000);
Jason Gilbert

retorne o tempo em -v
Shauket Sheikh 13/05

23

Para obter milissegundos para a data atual.

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 Doublenão tem propriedade em milissegundos. Date().timeIntervalSince1970 * 1000
Leo Dabus

10

Pode ser útil conhecer os CodeTimestamps, que fornecem um invólucro para as funções de temporização baseadas em mach. Isso fornece dados de tempo de resolução em nanossegundos - 1000000x mais preciso que milissegundos. Sim, um milhão de vezes mais preciso. (Os prefixos são milli, micro, nano, cada 1000x mais preciso que o anterior.) Mesmo se você não precisar dos carimbos de data e hora do CodeTim, verifique o código (é de código aberto) para ver como eles usam mach para obter os dados de tempo. Isso seria útil quando você precisar de mais precisão e desejar uma chamada de método mais rápida que a abordagem NSDate.

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


E você provavelmente precisará de um -fno-objc-arcse você estiver usando ARC :)
Dan Rosenstark


3
O código-fonte ligada a partir da página está aqui: github.com/tylerneylon/moriarty
Tomas Andrle

8
// Timestamp after converting to milliseconds.

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

6

Eu precisava de um NSNumberobjeto contendo o resultado exato de [[NSDate date] timeIntervalSince1970]. Como essa função foi chamada várias vezes e eu realmente não precisava criar um NSDateobjeto, o desempenho não foi ótimo.

Portanto, para obter o formato que a função original estava fornecendo, tente o seguinte:

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

O que deve fornecer exatamente o mesmo resultado que [[NSDate date] timeIntervalSince1970]


4

CFAbsoluteTimeGetCurrent ()

O tempo absoluto é medido em segundos em relação à data de referência absoluta de 1 de janeiro de 2001 00:00:00 GMT. Um valor positivo representa uma data após a data de referência, um valor negativo representa uma data antes dele. Por exemplo, o tempo absoluto -32940326 é equivalente a 16 de dezembro de 1999 às 17:54:34. Chamadas repetidas para esta função não garantem resultados crescentes monotonicamente. A hora do sistema pode diminuir devido à sincronização com referências de hora externas ou devido a uma alteração explícita do relógio pelo usuário.


4

Tente o seguinte:

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;

Neste exemplo, dateWithTimeIntervalSince1970 é usado em combinação com o formatador "AAAA-MM-dd HH: mm: ss.SSS" que retornará a data com ano, mês, dia e hora com horas, minutos, segundos e milissegundos . Veja o exemplo: "02-12-2015 04: 43: 15.008". Eu usei o NSString para ter certeza de que o formato será escrito anteriormente.


4

Esta é basicamente a mesma resposta postada por @TristanLorach, recodificada para o 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

Isto é o que eu usei para Swift

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

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

usou este site para verificar a precisão http://currentmillis.com/


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

Por favor, adicione um pouco de explicação ao seu código de tal forma que outros possam aprender com ele - especialmente se você postar uma resposta a uma pergunta que já tem um monte de respostas upvoted
Nico Haase

0

[NSDate timeIntervalSinceReferenceDate]é outra opção, se você não deseja incluir a estrutura Quartz. Retorna um duplo, representando 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];
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.