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
Há 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.