iPhone: jak uzyskać bieżące milisekundy?


Odpowiedzi:


273
[[NSDate date] timeIntervalSince1970];

Zwraca liczbę sekund od epoki jako podwójną. Jestem prawie pewien, że możesz uzyskać dostęp do milisekund z części ułamkowej.


29
nie zabije nikogo, kto napisze to w ten sposób: NSTimeInterval myInterval = NSDate.timeIntervalSince1970; // wszystkie te nawiasy są naprawdę staromodne, jeśli mnie o to zapytasz.
Pizzaiola Gorgonzola

11
„te nawiasy” to nowsza wersja składni zgodnie z stackoverflow.com/q/11474284/209828
Matthew

119
„te nawiasy” są celem-c. Jeśli chcesz opracować dla systemu iOS, prawdopodobnie powinieneś się z nimi dobrze czuć.
Ampers4nd

5
Używam tej metody od jakiegoś czasu i zdałem sobie sprawę, że może zwrócić wcześniejszą wartość, gdy wywołasz ją po kilku milisekundach (np. Zadzwoń kolejno, a możesz nie skończyć z rosnącą sekwencją)
Ege Akpinar

5
[NSDate timeIntervalSinceReferenceDate]jest tańsze. (Chociaż odnosi się do innej „epoki” - jeśli chcesz, aby 1970 dodała stałą NSTimeIntervalSince1970.)
Hot Licks,

311

Jeśli chcesz użyć tego do względnego pomiaru czasu (na przykład do gier lub animacji), wolę użyć CACurrentMediaTime ()

double CurrentTime = CACurrentMediaTime();

Który jest zalecanym sposobem; NSDateczerpie z sieciowego zegara synchronizacji i od czasu do czasu czkawka przy ponownej synchronizacji z siecią.

Zwraca bieżący czas bezwzględny w sekundach.


Jeśli chcesz tylko część dziesiętną (często używaną podczas synchronizacji animacji),

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

7
Wydaje się jednak, że zajmuje dwukrotnie więcej czasu niż [[data NSDate] timeIntervalSince1970]. Zmierzyłem 0,065 ms wobec 0,033 ms dla 15000 połączeń.
Kay

1
Uwaga: aby wykonać to wywołanie, musisz dołączyć Quartz Framework i #import <Quartz / CABase.h>.
BadPirate

8
Ups - to import #import <QuartzCore / CAAnimation.h>
BadPirate

6
Dla nowych użytkowników Xcode (takich jak ja) „włącz Quartz Framework” oznacza dodanie go do zestawu bibliotek w „Link Binary With Libraries”.
Gabe Johnson,

3
Jeśli ktoś szuka tego w odniesieniu do SpriteKit, „bieżącym czasem” w metodzie aktualizacji SKScene jest rzeczywiście CACurrentMediaTime ();
Anthony Mattox

92

Testowałem wszystkie pozostałe odpowiedzi na iPhonie 4S i iPadzie 3 (wersje kompilacji). CACurrentMediaTimema najmniejszy narzut przy niewielkim marginesie. timeIntervalSince1970jest znacznie wolniejszy niż inne, prawdopodobnie z powodu NSDatenarzutu tworzenia instancji, chociaż może nie mieć znaczenia w wielu przypadkach użycia.

Polecam, CACurrentMediaTimejeśli chcesz jak najmniej narzutu i nie przeszkadza dodanie zależności Quartz Framework. Lub gettimeofdayjeśli przenośność jest dla Ciebie priorytetem.

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, Chociaż jest to oczywiście bardzo pouczające i pomocne, nie nazwałbym tego doskonale pracą inżynierską bez zobaczenia kodu źródłowego;)
Steven Lu

2
Uważaj jednak na ten problem: bendodson.com/weblog/2013/01/29/ca-current-media-time Ten zegar najwyraźniej zatrzymuje się, gdy urządzenie przechodzi w tryb uśpienia.
mojuba,

1
Jest NSTimeIntervalSince1970makro, które jest najszybsze.
ozgur

@ozgur NSTimeIntervalSince1970to stała opisująca sekundy między 1970-01-01 a „datą odniesienia” (tj. 2001-01-01), więc zawsze jest równa 978307200
YourMJK

53

W Swift możemy wykonać funkcję i wykonać następujące czynności

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

var currentTime = getCurrentMillis()

Chociaż działa dobrze w Swift 3.0, ale możemy zmodyfikować i użyć tej Dateklasy zamiastNSDate w 3.0

Swift 3.0

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

var currentTime = getCurrentMillis()

30

Do tej pory znalazłem gettimeofdaydobre rozwiązanie na iOS (iPad), kiedy chcesz przeprowadzić ocenę interwału (powiedzmy, ilość klatek na sekundę, czas wyświetlania ramki renderowania ...):

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

2
Też mi się podoba, ponieważ jest bardzo przenośny. Zauważ, że w zależności od systemu operacyjnego może być konieczne użycie „długiego długiego” zamiast „długiego” i podobnie rzutowania time.tv_sec na „long long” przed wykonaniem pozostałej części obliczeń.
AbePralle,

statyczny bez znaku długi getMStime (void) {struct timeval time; gettimeofday (i czas, NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); }
David H

Co ciekawe, działa to dobrze na moim iPhonie 5S i Macu, ale zwraca niewłaściwą wartość na iPadzie 3.
Hyndrix

Aby uniknąć uzyskania liczb ujemnych, musiałem rzucić przed matematyką: int64_t wynik = ((int64_t) tv.tv_sec * 1000) + ((int64_t) tv.tv_usec / 1000);
Jason Gilbert

czas powrotu w -ve
Shauket Sheikh

23

Aby uzyskać milisekundy dla bieżącej daty.

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

Szybki 3

let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds

2
TimeIntervalaka Doublenie ma właściwości milisekund. Date().timeIntervalSince1970 * 1000
Leo Dabus

10

Warto wiedzieć o CodeTimestamps, które zapewniają owijanie wokół funkcji czasowych opartych na machu. To daje dane czasowe o rozdzielczości nanosekundowej - 1000000x bardziej precyzyjne niż milisekundy. Tak, milion razy bardziej precyzyjnie. (Prefiksy to milli, micro, nano, każdy 1000 razy bardziej precyzyjny niż ostatni.) Nawet jeśli nie potrzebujesz CodeTimestamps, sprawdź kod (jest to oprogramowanie typu open source), aby zobaczyć, w jaki sposób używają mach, aby uzyskać dane o taktowaniu. Byłoby to przydatne, gdy potrzebujesz większej precyzji i chcesz szybszego wywołania metody niż podejście NSDate.

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


I prawdopodobnie będziesz potrzebować, -fno-objc-arcjeśli używasz ARC :)
Dan Rosenstark


3
Kod źródłowy, do którego link znajduje się na stronie, znajduje się tutaj: github.com/tylerneylon/moriarty
Tomas

8
// Timestamp after converting to milliseconds.

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

6

Potrzebowałem NSNumberobiektu zawierającego dokładny wynik [[NSDate date] timeIntervalSince1970]. Ponieważ ta funkcja była wywoływana wiele razy i tak naprawdę nie musiałem tworzyćNSDate obiektu, wydajność nie była świetna.

Aby uzyskać format, który dawała mi oryginalna funkcja, spróbuj tego:

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

Co powinno dać ci dokładnie taki sam wynik jak [[NSDate date] timeIntervalSince1970]


4

CFAbsoluteTimeGetCurrent ()

Czas bezwzględny mierzony jest w sekundach w stosunku do bezwzględnej daty odniesienia 1 stycznia 2001 r. 00:00:00 GMT. Wartość dodatnia reprezentuje datę po dacie odniesienia, wartość ujemna reprezentuje datę przed nią. Na przykład czas bezwzględny -32940326 jest równoważny 16 grudnia 1999 o 17:54:34. Powtarzane wywołania tej funkcji nie gwarantują monotonicznie rosnących wyników. Czas systemowy może ulec skróceniu z powodu synchronizacji z zewnętrznymi odniesieniami do czasu lub z powodu wyraźnej zmiany zegara przez użytkownika.


4

Spróbuj tego :

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;

W tym przykładzie dateWithTimeIntervalSince1970 jest używany w połączeniu z formatyzatorem @ „RRRR-MM-dd GG: mm: ss.SSS”, który zwraca datę z rokiem, miesiącem, dniem i godziną z godzinami, minutami, sekundami i milisekundami . Zobacz przykład: „2015-12-02 04: 43: 15.008”. Użyłem NSString, aby mieć pewność, że format zostanie wcześniej zapisany.


4

Jest to w zasadzie ta sama odpowiedź, którą opublikował @TristanLorach, właśnie przerobiony dla 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

Tego właśnie użyłem w Swift

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

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

używał tej strony do weryfikacji dokładności http://currentmillis.com/


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

Proszę dodać jakieś wyjaśnienie do kodu tak, że inni mogą uczyć się od niego - szczególnie jeśli po odpowiedzi na pytanie, które już ma dużo upvoted odpowiedzi
Nico Haase

0

[NSDate timeIntervalSinceReferenceDate]to kolejna opcja, jeśli nie chcesz uwzględniać ramy Quartz. Zwraca podwójny, reprezentujący sekundy.


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];
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.