iPhone: วิธีรับมิลลิวินาทีปัจจุบัน


คำตอบ:


273
[[NSDate date] timeIntervalSince1970];

มันจะส่งกลับจำนวนวินาทีตั้งแต่ยุคเป็นสองเท่า ฉันเกือบจะแน่ใจว่าคุณสามารถเข้าถึงมิลลิวินาทีจากส่วนที่เป็นเศษส่วน


29
มันไม่ได้ฆ่าใครให้เขียนอย่างนี้: NSTimeInterval myInterval = NSDate.timeIntervalSince1970; // วงเล็บทั้งหมดนั้นค่อนข้างล้าสมัยถ้าคุณถามฉัน
Pizzaiola Gorgonzola

11
'วงเล็บเหล่านั้น' เป็นเวอร์ชันใหม่ของไวยากรณ์ตามstackoverflow.com/q/11474284/209828
Matthew

119
"วงเล็บเหล่านั้น" เป็นวัตถุประสงค์ -c ถ้าคุณต้องการพัฒนาสำหรับ iOS คุณอาจจะคุ้นเคยกับมัน
Ampers4nd

5
ฉันใช้วิธีนี้มาระยะหนึ่งแล้วก็รู้ว่ามันสามารถคืนค่าก่อนหน้านี้เมื่อคุณเรียกมันหลังจากสองสามไมล์ (เช่นเรียกว่าติดต่อกันและคุณอาจไม่ได้ลำดับที่เพิ่มขึ้น)
Ege Akpinar

5
[NSDate timeIntervalSinceReferenceDate]ราคาถูกกว่า (แม้ว่าจะอ้างอิงถึง "ยุค" ที่แตกต่าง - ถ้าคุณต้องการ 1970 เพิ่มค่าคงที่NSTimeIntervalSince1970)
Hot Licks

311

หากคุณกำลังใช้สิ่งนี้เพื่อกำหนดเวลาแบบสัมพัทธ์ (เช่นเกมหรือภาพเคลื่อนไหว) ฉันควรใช้CACurrentMediaTime ()

double CurrentTime = CACurrentMediaTime();

ซึ่งเป็นวิธีที่แนะนำ NSDateดึงจากซิงก์นาฬิกาเครือข่ายและบางครั้งจะสะอึกเมื่อซิงก์อีกครั้งกับเครือข่าย

ส่งคืนเวลาสัมบูรณ์ปัจจุบันเป็นวินาที


หากคุณต้องการเฉพาะส่วนทศนิยม (มักใช้เมื่อทำการซิงค์ภาพเคลื่อนไหว)

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

7
แต่ดูเหมือนว่าจะใช้เวลาเป็นสองเท่าสำหรับ [[วันที่ NSDate] timeIntervalSince1970] ฉันวัด 0.065ms เทียบกับ 0.033 มิลลิวินาทีในการโทร 15000 ครั้ง
Kay

1
หมายเหตุคุณจะต้องรวม Quartz Framework และ #import <Quartz / CABase.h> เพื่อทำการโทร
BadPirate

8
อ๊ะ - นั่นนำเข้า #import <QuartzCore / CAAnimation.h>
BadPirate

6
สำหรับผู้ที่ยังใหม่กับ Xcode (เช่นฉัน) "รวม Quartz Framework" หมายถึงการเพิ่มลงในชุดของห้องสมุดใน "Link Binary With Libraries"
Gabe Johnson

3
หากใครที่กำลังมองหาสิ่งนี้เกี่ยวข้องกับ SpriteKit 'เวลาปัจจุบัน' ในวิธีการอัพเดตของ SKScene นั้นเป็น CACurrentMediaTime () อย่างแน่นอน
Anthony Mattox

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 ในขณะนี้จะเห็นได้ชัดให้ข้อมูลที่เป็นประโยชน์มากและฉันจะไม่เรียกมันว่างานด้านวิศวกรรมที่ดีโดยไม่ต้องเห็นรหัสที่มาบาง;)
สตีเว่น Lu

2
ระวังปัญหานี้แม้ว่า: bendodson.com/weblog/2013/01/29/ca-current-media-timeดูเหมือนว่านาฬิกานี้จะหยุดเมื่ออุปกรณ์เข้าสู่โหมดสลีป
mojuba

1
มีNSTimeIntervalSince1970มาโครที่เร็วที่สุด
ozgur

@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

สวิฟท์ 3.0

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

var currentTime = getCurrentMillis()

30

จนถึงตอนนี้ฉันพบgettimeofdayวิธีแก้ปัญหาที่ดีใน iOS (iPad) เมื่อคุณต้องการทำการประเมินช่วงเวลา (พูด, framerate, ช่วงเวลาของเฟรมการเรนเดอร์ ... ):

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

2
ฉันชอบสิ่งนี้เช่นกันเนื่องจากพกพาได้มาก โปรดทราบว่าขึ้นอยู่กับระบบปฏิบัติการที่คุณอาจต้องใช้ 'long long' แทน 'long' และ cast time.tv_sec ในทำนองเดียวกันกับ 'long long' ก่อนทำการคำนวณที่เหลือ
AbePralle

getMStime แบบยาวที่ไม่ได้ลงนามแบบคงที่ (เป็นโมฆะ) {เวลาตามโครงสร้างช่วงเวลา gettimeofday (& เวลา NULL); return (time.tv_sec * 1000) + (time.tv_usec / 1000); }
เดวิด H

น่าสนใจใช้งานได้ดีกับ iPhone 5S และ Mac ของฉัน แต่คืนค่าผิดบน iPad 3
Hyndrix

เพื่อหลีกเลี่ยงการได้รับจำนวนลบฉันต้องคำนวณก่อนคณิตศาสตร์: int64_t result = ((int64_t) tv.tv_sec * 1000) + ((int64_t) tv.tv_usec / 1000);
jason gilbert

มันกลับเวลาใน -ve
Shauket Sheikh

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
TimeIntervalอาคาDoubleไม่มีคุณสมบัติเป็นมิลลิวินาที Date().timeIntervalSince1970 * 1000
Leo Dabus

10

มันอาจจะมีประโยชน์ที่จะรู้เกี่ยวกับ CodeTimestamps ซึ่งให้เสื้อคลุมรอบฟังก์ชั่นการจับเวลาตามจักร สิ่งนี้จะให้ข้อมูลระยะเวลาความละเอียดระดับนาโนวินาทีของคุณ - แม่นยำมากขึ้น 1000000x กว่ามิลลิวินาที ใช่แม่นยำกว่าล้านเท่า (คำนำหน้าคือ milli, micro, nano, 1000x แต่ละอันแม่นยำกว่าครั้งสุดท้าย) แม้ว่าคุณไม่ต้องการ CodeTimestamps ลองดู code (มันเป็นโอเพ่นซอร์ส) เพื่อดูว่าพวกเขาใช้ mach เพื่อรับข้อมูลเวลาได้อย่างไร สิ่งนี้จะมีประโยชน์เมื่อคุณต้องการความแม่นยำมากขึ้นและต้องการการเรียกใช้วิธีที่เร็วกว่าวิธีของ NSDate

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


และคุณอาจจะต้องมี-fno-objc-arcถ้าคุณกำลังใช้ ARC :)
แดน Rosenstark


3
ซอร์สโค้ดที่เชื่อมโยงจากหน้านี้อยู่ที่นี่: github.com/tylerneylon/moriarty
Tomas Andrle


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 การเรียกฟังก์ชันนี้ซ้ำ ๆ ไม่รับประกันผลลัพธ์ที่เพิ่มขึ้นแบบ monotonically เวลาของระบบอาจลดลงเนื่องจากการซิงโครไนซ์กับการอ้างอิงเวลาภายนอกหรือเนื่องจากการเปลี่ยนแปลงของผู้ใช้อย่างชัดเจนของนาฬิกา


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 ใช้ร่วมกับตัวจัดรูปแบบ @ "YYYY-MM-dd HH: mm: 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)
   }


1

นี่คือสิ่งที่ฉันใช้สำหรับสวิฟท์

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)

โปรดเพิ่มคำอธิบายลงในรหัสของคุณเพื่อให้ผู้อื่นสามารถเรียนรู้ได้โดยเฉพาะอย่างยิ่งถ้าคุณโพสต์คำตอบสำหรับคำถามที่มีคำตอบ upvoted แล้วจำนวนมาก
Nico Haase

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];
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.