iPhone: Як отримати поточні мілісекунди?


Відповіді:


273
[[NSDate date] timeIntervalSince1970];

Він повертає кількість секунд з епохи як подвійний. Я майже впевнений, що ви можете отримати доступ до мілісекунд з дробової частини.


29
це нікого не вбиває, щоб написати це так: NSTimeInterval myInterval = NSDate.timeIntervalSince1970; // всі ці дужки справді старомодні, якщо ви запитаєте мене.
Pizzaiola Gorgonzola

11
"ці дужки" - це новіша версія синтаксису відповідно до stackoverflow.com/q/11474284/209828
Матвій

119
"ці дужки" об'єктивні-c. Якщо ви хочете розробитись для iOS, вам, мабуть, вам буде комфортно.
Ampers4nd

5
Я деякий час використовував цей метод і зрозумів, що він може повернути більш раннє значення, коли ви викликаєте його через пару мілісекунд (наприклад, дзвоніть йому послідовно, і ви, можливо, не закінчитеся із збільшенням послідовності)
Еге Акпінар,

5
[NSDate timeIntervalSinceReferenceDate]дешевше. (Хоча він посилається на іншу "епоху" - якщо ви хочете 1970 додати константу NSTimeIntervalSince1970.)
Hot Licks

311

Якщо ви дивитесь на те, щоб використовувати це для відносного часу (наприклад, для ігор чи анімації), я б краще скористатися CACurrentMediaTime ()

double CurrentTime = CACurrentMediaTime();

Який рекомендований спосіб; NSDateвитягує з мережевого синхронічного годинника і періодично буде гикати, коли повторно синхронізується з мережею.

Він повертає поточний абсолютний час у секундах.


Якщо ви хочете лише десяткову частину (часто використовується під час синхронізації анімації),

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

7
Але це, здається, займає вдвічі більше часу, необхідного для [[дати NSDate] timeIntervalSince1970]. Я вимірював 0,065 мс і 0,033 мс на 15000 дзвінків.
Кей

1
Зверніть увагу: для здійснення цього дзвінка вам потрібно буде включити Quartz Framework і #import <Quartz / CABase.h>.
BadPirate

8
Уопс - ось імпорт #import <QuartzCore / CAAnimation.h>
BadPirate

6
Для тих, хто не входить до Xcode (як я), "включати Quartz Framework" означає додавання його до набору бібліотек у "Посилання бінарних із бібліотеками".
Гейб Джонсон

3
Якщо хтось шукає цього стосовно SpriteKit, "поточний час" у способі оновлення SKScene дійсно є CACurrentMediaTime ();
Ентоні Маттокс

92

Я порівняв усі інші відповіді на iPhone 4S та iPad 3 (версії версій). CACurrentMediaTimeмає найменші накладні витрати з невеликим запасом. timeIntervalSince1970набагато повільніше, ніж інші, ймовірно, через NSDateекземпляри накладних витрат, хоча це може не мати значення для багатьох випадків використання.

Я б рекомендував, CACurrentMediaTimeякщо ви хочете як мінімум, і не проти додавати залежність від Quartz Framework. Абоgettimeofday якщо портативність є для вас пріоритетною.

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, Хоча це, очевидно, дуже інформативно і корисно, я б точно не назвав це великою інженерною роботою, не побачивши якогось вихідного коду;)
Стівен Лу

2
Остерігайтеся цього питання, однак: bendodson.com/weblog/2013/01/29/ca-current-media-time Цей годинник, мабуть, зупиняється, коли пристрій переходить у режим сну.
моджуба

1
Є NSTimeIntervalSince1970макрос, який найшвидший.
озгур

@ozgur NSTimeIntervalSince1970- це константа, що описує секунди між 1970-01-01 та "опорною датою" (тобто 2001-01-01), тому вона завжди дорівнює 978307200
YourMJK

53

У Swift ми можемо зробити функцію і зробити наступне

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

var currentTime = getCurrentMillis()

Хоча його працює відмінно в Swift 3.0 , але ми можемо змінити і використовувати Dateклас замість NSDateв 3,0

Swift 3.0

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

var currentTime = getCurrentMillis()

30

Поки я знайшов gettimeofdayхороше рішення на iOS (iPad), коли потрібно виконати деяку оцінку інтервалу (скажімо, частоту кадрів, час кадру візуалізації ...):

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

2
Мені це теж подобається, оскільки він дуже портативний. Зауважте, що залежно від ОС вам може знадобитися використовувати "long long" замість "long" і так само віддавати time.tv_sec до "long long", перш ніж робити решту обчислення.
AbePralle

статичний неподписаний довгий getMStime (void) {структура timeval time; gettimeofday (& час, NULL); повернення (time.tv_sec * 1000) + (time.tv_usec / 1000); }
Девід Н

Цікаво, що це добре працює на моїх iPhone 5S та Mac, але повертає неправильне значення на iPad 3.
Hyndrix

Щоб уникнути отримання від’ємних чисел, я повинен був подати перед математикою: int64_t result = ((int64_t) tv.tv_sec * 1000) + ((int64_t) tv.tv_usec / 1000);
Jason Gilbert

це час повернення в -ве
Шоукет Шейх

23

Щоб отримати мілісекунди для поточної дати.

Swift 4+:

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

18

Швидкий 2

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

Швидкий 3

let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds

2
TimeIntervalaka Doubleне має властивості мілісекунд. Date().timeIntervalSince1970 * 1000
Лев Дабус

10

Це може бути корисно знати про CodeTimestamps, які забезпечують обгортку навколо функцій синхронізації на основі машин. Це дає вам дані про часовий дозвіл наносекунди - 1000000x точніші за мілісекунди. Так, в мільйон разів точніше. (Префікси - мілі, мікро, нано, кожен 1000 разів точніший за останній.) Навіть якщо вам не потрібні позначки CodeTimestaks, перегляньте код (це відкритий код), щоб побачити, як вони використовують Mach для отримання даних про терміни. Це було б корисно, коли вам потрібна більш точна та хочете швидший виклик методу, ніж підхід NSDate.

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


І вам, мабуть, знадобиться, -fno-objc-arcякщо ви використовуєте ARC :)
Dan Rosenstark


3
Вихідний код, пов’язаний зі сторінкою, знаходиться тут: github.com/tylerneylon/moriarty
Tomas Andrle

8
// Timestamp after converting to milliseconds.

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

6

Мені знадобився NSNumberоб'єкт, що містить точний результат [[NSDate date] timeIntervalSince1970]. Оскільки цю функцію викликали багато разів, і мені не потрібно було створюватиNSDate об'єкт, продуктивність була не великою.

Отож, щоб отримати формат, який давала мені оригінальна функція, спробуйте це:

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

Що має дати вам точно такий же результат, як [[NSDate date] timeIntervalSince1970]


4

CFAbsoluteTimeGetCurrent ()

Абсолютний час вимірюється в секундах відносно абсолютної опорної дати 1 січня 2001 00:00:00 GMT. Позитивне значення являє собою дату після опорної дати, негативне значення - дату перед нею. Наприклад, абсолютний час -32940326 еквівалентно 16 грудня 1999 р. О 17:54:34. Повторні дзвінки на цю функцію не гарантують монотонно зростаючих результатів. Системний час може скорочуватися через синхронізацію із зовнішніми посиланнями часу або через явну зміну годинника користувачем.


4

Спробуйте це :

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;

У цьому прикладі dateWithTimeIntervalSince1970 використовується в поєднанні форматера @ "РРРР-ММ-ДД HH: мм: ss.SSS", який повертає дату з роком, місяцем, днем ​​і часом із годинами, хвилинами, секундами та мілісекундами . Дивіться приклад: "2015-12-02 04: 43: 15.008". Я використовував NSString, щоб переконатися, що формат буде написаний раніше.


4

Це в основному та сама відповідь, яку опублікував @TristanLorach, щойно перероблена для 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

Це те, що я використав для Swift

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

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

використовували цей сайт для перевірки точності http://currentmillis.com/


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

Будь-ласка, додайте до свого коду пояснення, щоб інші могли дізнатися з нього, особливо якщо ви опублікували відповідь на питання, на яке вже багато відповідей,
Ніко Хааз,

0

[NSDate timeIntervalSinceReferenceDate]інший варіант, якщо ви не хочете включати рамки Quartz. Він повертає дубль, представляючи секунди.


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];
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.