ค้นหาความแตกต่างเป็นวินาทีระหว่าง NSDates เป็นจำนวนเต็มโดยใช้ Swift


100

ฉันกำลังเขียนโค้ดโดยที่ฉันต้องการกำหนดระยะเวลาที่ปุ่มค้างไว้ ในการทำเช่นนั้นฉันบันทึกNSDate()เวลาที่กดปุ่มและลองใช้timeIntervalSinceDateฟังก์ชันเมื่อปล่อยปุ่ม ดูเหมือนจะใช้งานได้ แต่ฉันไม่พบวิธีใดในการพิมพ์ผลลัพธ์หรือเปลี่ยนเป็นจำนวนเต็ม

var timeAtPress = NSDate() 

@IBAction func pressed(sender: AnyObject) {
    println("pressed")
    timeAtPress = NSDate()
}

@IBAction func released(sender: AnyObject) {
    println("released")
    var elapsedTime = NSDate.timeIntervalSinceDate(timeAtPress)
    duration = ???
}

ฉันเคยเห็นคำถามคล้าย ๆ กันนี้ แต่ฉันไม่รู้จัก C ดังนั้นฉันจึงเข้าใจคำตอบที่ได้รับยาก หากมีวิธีที่มีประสิทธิภาพมากขึ้นในการค้นหาระยะเวลาที่กดปุ่มค้างไว้ฉันยินดีรับข้อเสนอแนะ ขอบคุณล่วงหน้า.

คำตอบ:


221

ความพยายามในการคำนวณของคุณelapsedTimeไม่ถูกต้อง ใน Swift 3 จะเป็น:

let elapsed = Date().timeIntervalSince(timeAtPress)

สังเกต()หลังการDateอ้างอิง Date()instantiates วัตถุวันที่ใหม่แล้วผลตอบแทนที่แตกต่างของเวลาระหว่างที่และtimeIntervalSince timeAtPressซึ่งจะส่งคืนค่าทศนิยม (ในทางเทคนิค a TimeInterval)

หากคุณต้องการให้มีการตัดทอนเป็นIntค่าคุณสามารถใช้:

let duration = Int(elapsed)

และ BTW คำจำกัดความของtimeAtPressตัวแปรของคุณไม่จำเป็นต้องสร้างอินสแตนซ์Dateวัตถุ ฉันคิดว่าคุณตั้งใจ:

var timeAtPress: Date!

สิ่งนี้กำหนดตัวแปรเป็นDateตัวแปร (ตัวแปรที่ไม่ได้ปิดโดยปริยาย) แต่คุณอาจจะเลื่อนการสร้างอินสแตนซ์จริงของตัวแปรนั้นออกไปจนกว่าpressedจะมีการเรียก


หรือฉันมักจะใช้CFAbsoluteTimeGetCurrent()เช่น

var start: CFAbsoluteTime!

และเมื่อฉันต้องการตั้งค่าstartTimeฉันจะทำสิ่งต่อไปนี้:

start = CFAbsoluteTimeGetCurrent()

และเมื่อฉันต้องการคำนวณจำนวนวินาทีที่ผ่านไปฉันจะทำดังต่อไปนี้:

let elapsed = CFAbsoluteTimeGetCurrent() - start

เป็นที่น่าสังเกตว่าCFAbsoluteTimeGetCurrentเอกสารนี้เตือนเรา:

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

ซึ่งหมายความว่าหากคุณโชคไม่ดีพอที่จะวัดเวลาที่ผ่านไปเมื่อมีการปรับเปลี่ยนอย่างใดอย่างหนึ่งคุณอาจต้องคำนวณเวลาที่ผ่านไปไม่ถูกต้อง นี่เป็นจริงสำหรับNSDate/ การDateคำนวณด้วย ปลอดภัยที่สุดในการใช้การmach_absolute_timeคำนวณตามเกณฑ์ (ทำได้ง่ายที่สุดด้วยCACurrentMediaTime):

let start = CACurrentMediaTime()

และ

let elapsed = CACurrentMediaTime() - start

การใช้งานนี้mach_absolute_timeแต่หลีกเลี่ยงบางส่วนของความซับซ้อนของมันที่ระบุไว้ในทางเทคนิค Q & A QA1398

อย่างไรก็ตามโปรดจำไว้ว่าCACurrentMediaTime/ mach_absolute_timeจะถูกรีเซ็ตเมื่อรีบูตอุปกรณ์ ดังนั้นบรรทัดด้านล่างถ้าคุณต้องการการคำนวณเวลาที่ผ่านไปที่ถูกต้องในขณะที่ app CACurrentMediaTimeยังทำงานอยู่ให้ใช้งาน แต่ถ้าคุณจะบันทึกเวลาเริ่มต้นนี้ไว้ในที่เก็บข้อมูลถาวรซึ่งคุณอาจจำได้เมื่อแอปเริ่มต้นใหม่ในวันที่ในอนาคตคุณต้องใช้DateหรือCFAbsoluteTimeGetCurrentและอยู่กับความไม่ถูกต้องที่อาจเกิดขึ้น


4
ว้าวขอบคุณ Rob! คำตอบของคุณมีประโยชน์มากและเข้าใจง่าย ฉันขอบคุณมากสำหรับเคล็ดลับเกี่ยวกับ CFAbsoluteTime ฉันจะใช้มันแน่นอน!
Erik

มิติของ timeIntervalSinceDate คืออะไร?
eugene

จะส่งกลับ a TimeIntervalซึ่งวัดเป็นวินาที
Rob

22

NSDate () และ NSCalendar () ดูเหมือนเป็นตัวเลือกที่ดี ใช้การคำนวณปฏิทินและปล่อยส่วนคณิตศาสตร์จริงไว้ในกรอบ นี่คือตัวอย่างสั้น ๆ ของการหาวินาทีระหว่างสองNSDate()

let startDate = NSDate()
let endDate = NSDate()
let calendar = NSCalendar.currentCalendar()
let dateComponents = calendar.components(NSCalendarUnit.CalendarUnitSecond, fromDate: startDate, toDate: endDate, options: nil)
let seconds = dateComponents.second
println("Seconds: \(seconds)")

ด้วยเหตุผลบางอย่างสิ่งนี้จะคืนค่า 0 ให้ฉันเสมอแม้ว่าวันที่จะห่างกันหนึ่งชั่วโมง
Markymark

11

ตามคำตอบของ Freddy นี่คือฟังก์ชั่นใน swift 3:

let start = Date()
let end = Date(timeIntervalSince1970: 100)
let calendar = Calendar.current
let unitFlags = Set<Calendar.Component>([ .second])
let datecomponents = calendar.dateComponents(unitFlags, from: start, to: end)
let seconds = datecomponents.second
print(String(describing: seconds))

1
ขอบคุณ @LagMaster มีความสุขที่ได้เห็น swift กำลังใช้คำนำหน้า NS
Freddy


0

นี่คือวิธีที่คุณจะได้รับความแตกต่างใน Swift 3 เวอร์ชันล่าสุด

let calendar = NSCalendar.current
var compos:Set<Calendar.Component> = Set<Calendar.Component>()
compos.insert(.second)
compos.insert(.minute)
let difference = calendar.dateComponents(compos, from: fromDate, to: toDate)
print("diff in minute=\(difference.minute!)") // difference in minute
print("diff in seconds=\(difference.second!)") // difference in seconds

ข้อมูลอ้างอิง: การรับความแตกต่างระหว่าง NSDates สองรายการใน (เดือน / วัน / ชั่วโมง / นาที / วินาที)


-1

สวิฟต์ 5

    let startDate = Date()
    let endDate = Date()
    let calendar = Calendar.current
    let dateComponents = calendar.compare(startDate, to: endDate, toGranularity: .second)
    let seconds = dateComponents.rawValue
    print("Seconds: \(seconds)")

2
สิ่งนี้ไม่ได้ให้ความแตกต่างเป็นวินาทีในรหัสเพียงอย่างเดียวไม่ว่าการเริ่มต้นจะมากกว่าหรือไม่
อรุณก

-6

สำหรับ Swift 3 วินาทีระหว่าง 2 ครั้งใน "hh: mm"

func secondsIn(_ str: String)->Int{
    var strArr = str.characters.split{$0 == ":"}.map(String.init)
    var sec = Int(strArr[0])! * 3600
    var sec1 = Int(strArr[1])! * 36
    print("sec")
    print(sec+sec1)
    return sec+sec1

}

การใช้งาน

var sec1 = secondsIn(shuttleTime)
var sec2 = secondsIn(dateToString(Date()))
print(sec1-sec2)

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