วิธีที่ดีที่สุดในการรับเวลาระบบมิลลิวินาทีในปัจจุบันคืออะไร?
วิธีที่ดีที่สุดในการรับเวลาระบบมิลลิวินาทีในปัจจุบันคืออะไร?
คำตอบ:
[[NSDate date] timeIntervalSince1970];
มันจะส่งกลับจำนวนวินาทีตั้งแต่ยุคเป็นสองเท่า ฉันเกือบจะแน่ใจว่าคุณสามารถเข้าถึงมิลลิวินาทีจากส่วนที่เป็นเศษส่วน
[NSDate timeIntervalSinceReferenceDate]
ราคาถูกกว่า (แม้ว่าจะอ้างอิงถึง "ยุค" ที่แตกต่าง - ถ้าคุณต้องการ 1970 เพิ่มค่าคงที่NSTimeIntervalSince1970
)
หากคุณกำลังใช้สิ่งนี้เพื่อกำหนดเวลาแบบสัมพัทธ์ (เช่นเกมหรือภาพเคลื่อนไหว) ฉันควรใช้CACurrentMediaTime ()
double CurrentTime = CACurrentMediaTime();
ซึ่งเป็นวิธีที่แนะนำ NSDate
ดึงจากซิงก์นาฬิกาเครือข่ายและบางครั้งจะสะอึกเมื่อซิงก์อีกครั้งกับเครือข่าย
ส่งคืนเวลาสัมบูรณ์ปัจจุบันเป็นวินาที
หากคุณต้องการเฉพาะส่วนทศนิยม (มักใช้เมื่อทำการซิงค์ภาพเคลื่อนไหว)
let ct = CACurrentMediaTime().truncatingRemainder(dividingBy: 1)
ฉันเปรียบเทียบคำตอบอื่น ๆ ทั้งหมดใน 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
NSTimeIntervalSince1970
มาโครที่เร็วที่สุด
NSTimeIntervalSince1970
เป็นค่าคงที่อธิบายวินาทีระหว่าง 1970-01-01 และ "วันที่อ้างอิง" (เช่น 2001-01-01) ดังนั้นจึงเท่ากับ 978307200
ใน 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()
จนถึงตอนนี้ฉันพบgettimeofday
วิธีแก้ปัญหาที่ดีใน iOS (iPad) เมื่อคุณต้องการทำการประเมินช่วงเวลา (พูด, framerate, ช่วงเวลาของเฟรมการเรนเดอร์ ... ):
#include <sys/time.h>
struct timeval time;
gettimeofday(&time, NULL);
long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000);
เพื่อรับมิลลิวินาทีสำหรับวันที่ปัจจุบัน
Swift 4+:
func currentTimeInMilliSeconds()-> Int
{
let currentDate = Date()
let since1970 = currentDate.timeIntervalSince1970
return Int(since1970 * 1000)
}
สวิฟท์ 2
let seconds = NSDate().timeIntervalSince1970
let milliseconds = seconds * 1000.0
สวิฟท์ 3
let currentTimeInMiliseconds = Date().timeIntervalSince1970.milliseconds
TimeInterval
อาคาDouble
ไม่มีคุณสมบัติเป็นมิลลิวินาที Date().timeIntervalSince1970 * 1000
มันอาจจะมีประโยชน์ที่จะรู้เกี่ยวกับ 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 :)
// Timestamp after converting to milliseconds.
NSString * timeInMS = [NSString stringWithFormat:@"%lld", [@(floor([date timeIntervalSince1970] * 1000)) longLongValue]];
ฉันต้องการ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]
เวลาแน่นอนถูกวัดเป็นวินาทีเทียบกับวันที่อ้างอิงแน่นอนของ 1 มกราคม 2001 00:00:00 GMT ค่าบวกหมายถึงวันที่หลังจากวันที่อ้างอิงค่าลบหมายถึงวันที่ก่อนหน้านั้น ตัวอย่างเช่นเวลาสัมบูรณ์ -32940326 เทียบเท่ากับ 16 ธันวาคม 1999 เวลา 17:54:34 การเรียกฟังก์ชันนี้ซ้ำ ๆ ไม่รับประกันผลลัพธ์ที่เพิ่มขึ้นแบบ monotonically เวลาของระบบอาจลดลงเนื่องจากการซิงโครไนซ์กับการอ้างอิงเวลาภายนอกหรือเนื่องจากการเปลี่ยนแปลงของผู้ใช้อย่างชัดเจนของนาฬิกา
ลองสิ่งนี้:
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 เพื่อให้แน่ใจว่ารูปแบบจะถูกเขียนก่อนหน้านี้
นี่เป็นคำตอบเดียวกับที่โพสต์โดย @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)
}
func currentmicrotimeTimeMillis() -> Int64{
let nowDoublevaluseis = NSDate().timeIntervalSince1970
return Int64(nowDoublevaluseis*1000)
}
นี่คือสิ่งที่ฉันใช้สำหรับสวิฟท์
var date = NSDate()
let currentTime = Int64(date.timeIntervalSince1970 * 1000)
print("Time in milliseconds is \(currentTime)")
ใช้เว็บไซต์นี้เพื่อตรวจสอบความถูกต้องhttp://currentmillis.com/
let timeInMiliSecDate = Date()
let timeInMiliSec = Int (timeInMiliSecDate.timeIntervalSince1970 * 1000)
print(timeInMiliSec)
[NSDate timeIntervalSinceReferenceDate]
เป็นอีกตัวเลือกหนึ่งหากคุณไม่ต้องการรวมกรอบ Quartz มันจะส่งกลับสองครั้งคิดเป็นวินาที
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];