iPhone: come ottenere millisecondi attuali?


Risposte:


273
[[NSDate date] timeIntervalSince1970];

Restituisce il numero di secondi dall'epoca in doppio. Sono quasi sicuro che puoi accedere ai millisecondi dalla parte frazionaria.


29
non uccide nessuno a scriverlo in questo modo: NSTimeInterval myInterval = NSDate.timeIntervalSince1970; // tutte quelle parentesi sono davvero vecchio stile se me lo chiedi.
Pizzaiola Gorgonzola,

11
"Quelle parentesi" sono una versione più recente della sintassi secondo stackoverflow.com/q/11474284/209828
Matteo

119
"quelle parentesi" sono obiettivi-c. Se vuoi sviluppare per iOS, probabilmente dovresti metterti comodo con loro.
Ampers4,

5
Sto usando questo metodo da un po 'e ho capito che può restituire un valore precedente quando lo chiami dopo un paio di millisecondi (ad esempio, chiamalo consecutivamente e potresti non finire con una sequenza crescente)
Ege Akpinar

5
[NSDate timeIntervalSinceReferenceDate]è più economico. (Anche se fa riferimento a una "epoca" diversa - se vuoi il 1970 aggiungi la costante NSTimeIntervalSince1970.)
Hot Licks,

311

Se stai cercando di usarlo per i tempi relativi (ad esempio per giochi o animazioni) preferirei usare CACurrentMediaTime ()

double CurrentTime = CACurrentMediaTime();

Qual è il modo raccomandato; NSDateattinge dall'orologio di sincronizzazione in rete e occasionalmente si verifica un singhiozzo quando si sincronizza nuovamente con la rete.

Restituisce il tempo assoluto corrente, in secondi.


Se desideri solo la parte decimale (spesso utilizzata durante la sincronizzazione di animazioni),

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

7
Ma sembra impiegare il doppio del tempo necessario per [[data NSDate] timeIntervalSince1970]. Ho misurato 0,065 ms contro 0,033 ms su 15000 chiamate.
Kay,

1
Nota, per effettuare questa chiamata devi includere Quartz Framework e #import <Quartz / CABase.h>.
BadPirate,

8
Whoops - thats import #import <QuartzCore / CAAnimation.h>
BadPirate

6
Per quelli che non conoscono Xcode (come me) "includere Quartz Framework" significa aggiungerlo al set di librerie in "Link Binary With Libraries".
Gabe Johnson,

3
Se qualcuno lo sta cercando in relazione a SpriteKit, l '"ora corrente" nel metodo di aggiornamento di SKScene è effettivamente CACurrentMediaTime ();
Anthony Mattox,

92

Ho confrontato tutte le altre risposte su un iPhone 4S e iPad 3 (build di rilascio). CACurrentMediaTimeha il minimo sovraccarico di un piccolo margine. timeIntervalSince1970è molto più lento degli altri, probabilmente a causa del NSDatesovraccarico di istanza, anche se potrebbe non essere importante per molti casi d'uso.

Ti consiglierei CACurrentMediaTimese desideri il minimo sovraccarico e non ti dispiace aggiungere la dipendenza Quartz Framework. O gettimeofdayse la portabilità è una priorità per te.

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, anche se questo è ovviamente molto istruttivo e utile, non lo definirei esattamente un ottimo lavoro di ingegneria senza vedere un codice sorgente;)
Steven Lu

2
Attenzione però a questo problema: bendodson.com/weblog/2013/01/29/ca-current-media-time Questo orologio apparentemente si interrompe quando il dispositivo entra in modalità di sospensione .
Mojuba,

1
C'è una NSTimeIntervalSince1970macro che è la più veloce.
ozgur,

@ozgur NSTimeIntervalSince1970è una costante che descrive i secondi tra il 1970-01-01 e la "data di riferimento" (cioè 2001-01-01), quindi è sempre uguale a 978307200
YourMJK

53

In Swift possiamo fare una funzione e fare come segue

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

var currentTime = getCurrentMillis()

Anche se funziona bene in Swift 3.0 ma possiamo modificare e usare la Dateclasse invece che NSDatein 3.0

Swift 3.0

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

var currentTime = getCurrentMillis()

30

Finora ho trovato gettimeofdayuna buona soluzione su iOS (iPad), quando si desidera eseguire una valutazione dell'intervallo (ad esempio framerate, tempistica di un frame di rendering ...):

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

2
Mi piace anche questo perché è molto portatile. Si noti che, a seconda del sistema operativo, potrebbe essere necessario utilizzare 'long long' anziché un 'long' e allo stesso modo lanciare time.tv_sec su 'long long' prima di fare il resto del calcolo.
AbePralle l'

getMStime lungo senza segno statico (vuoto) {struct timeval time; gettimeofday (& time, NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); }
David H,

È interessante notare che questo funziona bene sul mio iPhone 5S e Mac ma restituisce un valore errato su un iPad 3.
Hyndrix,

Per evitare di ottenere numeri negativi ho dovuto lanciare prima della matematica: int64_t result = ((int64_t) tv.tv_sec * 1000) + ((int64_t) tv.tv_usec / 1000);
Jason Gilbert,

ritorna tempo in
-ve

23

Per ottenere millisecondi per la data corrente.

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 Doublenon ha proprietà in millisecondi. Date().timeIntervalSince1970 * 1000
Leo Dabus,

10

Può essere utile conoscere CodeTimestamps, che forniscono un wrapper per le funzioni di temporizzazione basate su mach. Ciò fornisce dati di temporizzazione a risoluzione di nanosecondi: 1000000x più precisi dei millisecondi. Sì, un milione di volte più preciso. (I prefissi sono milli, micro, nano, ognuno 1000 volte più preciso dell'ultimo.) Anche se non hai bisogno di CodeTimestamps, controlla il codice (è open source) per vedere come usano mach per ottenere i dati di temporizzazione. Ciò sarebbe utile quando hai bisogno di maggiore precisione e desideri una chiamata di metodo più veloce rispetto all'approccio NSDate.

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


E probabilmente avrai bisogno di un -fno-objc-arcse stai usando ARC :)
Dan Rosenstark,


3
Il codice sorgente collegato dalla pagina è qui: github.com/tylerneylon/moriarty
Tomas Andrle

8
// Timestamp after converting to milliseconds.

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

6

Avevo bisogno di un NSNumberoggetto contenente il risultato esatto di [[NSDate date] timeIntervalSince1970]. Poiché questa funzione è stata chiamata molte volte e non ho davvero bisogno di creare un NSDateoggetto, le prestazioni non sono state eccezionali.

Quindi per ottenere il formato che mi stava offrendo la funzione originale, prova questo:

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

Che dovrebbe darti lo stesso esatto risultato di [[NSDate date] timeIntervalSince1970]


4

CFAbsoluteTimeGetCurrent ()

Il tempo assoluto è misurato in secondi rispetto alla data di riferimento assoluta del 1 ° gennaio 2001 00:00:00 GMT. Un valore positivo rappresenta una data successiva alla data di riferimento, un valore negativo rappresenta una data precedente. Ad esempio, il tempo assoluto -32940326 è equivalente al 16 dicembre 1999 alle 17:54:34. Le chiamate ripetute a questa funzione non garantiscono risultati monotonicamente crescenti. L'ora del sistema può diminuire a causa della sincronizzazione con riferimenti temporali esterni o a causa di un esplicito cambio dell'orologio da parte dell'utente.


4

Prova questo :

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 questo esempio, dateWithTimeIntervalSince1970 viene utilizzato in combinazione con il formatter @ "AAAA-MM-gg HH: mm: ss.SSS" che restituirà la data con anno, mese, giorno e l'ora con ore, minuti, secondi e millisecondi . Vedi l'esempio: "2015-12-02 04: 43: 15.008". Ho usato NSString per essere sicuro che il formato sarà stato scritto prima.


4

Questa è sostanzialmente la stessa risposta pubblicata da @TristanLorach, appena modificata per 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

Questo è quello che ho usato per Swift

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

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

utilizzato questo sito per verificare l'accuratezza http://currentmillis.com/


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

Per favore aggiungi qualche spiegazione al tuo codice in modo che altri possano imparare da esso - specialmente se pubblichi una risposta a una domanda che ha già molte risposte votate
Nico Haase,

0

[NSDate timeIntervalSinceReferenceDate]è un'altra opzione, se non si desidera includere il framework Quartz. Restituisce un doppio, che rappresenta i secondi.


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];
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.