Temukan perbedaan dalam hitungan detik antara NSDates sebagai integer menggunakan Swift


99

Saya sedang menulis sepotong kode di mana saya ingin menghitung berapa lama sebuah tombol ditekan. Untuk melakukan itu saya merekam NSDate()saat tombol ditekan, dan mencoba menggunakan timeIntervalSinceDatefungsi saat tombol dilepas. Tampaknya berfungsi tetapi saya tidak dapat menemukan cara untuk mencetak hasil atau mengubahnya menjadi integer.

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 = ???
}

Saya telah melihat beberapa pertanyaan serupa, tetapi saya tidak tahu C jadi saya kesulitan memahami jawaban yang diberikan. Jika ada cara yang lebih efisien untuk mengetahui berapa lama tombol ditekan, saya terbuka untuk saran. Terima kasih sebelumnya.

Jawaban:


215

Upaya Anda untuk menghitung elapsedTimesalah. Di Swift 3, itu akan menjadi:

let elapsed = Date().timeIntervalSince(timeAtPress)

Perhatikan ()setelah Datereferensi. The Date()instantiates objek tanggal baru, dan kemudian timeIntervalSincemengembalikan perbedaan waktu antara itu dan timeAtPress. Itu akan mengembalikan nilai floating point (secara teknis, a TimeInterval).

Jika Anda ingin itu terpotong menjadi Intnilai, Anda bisa menggunakan:

let duration = Int(elapsed)

Dan, BTW, definisi Anda tentang timeAtPressvariabel tidak perlu membuat instance Dateobjek. Saya kira Anda bermaksud:

var timeAtPress: Date!

Itu mendefinisikan variabel sebagai Datevariabel (yang secara implisit tidak dibungkus), tetapi Anda mungkin akan menunda instansiasi aktual variabel itu sampai presseddipanggil.


Alternatifnya, saya sering menggunakan CFAbsoluteTimeGetCurrent(), misalnya,

var start: CFAbsoluteTime!

Dan ketika saya ingin mengatur startTime, saya melakukan hal berikut:

start = CFAbsoluteTimeGetCurrent()

Dan ketika saya ingin menghitung jumlah detik yang telah berlalu, saya melakukan hal berikut:

let elapsed = CFAbsoluteTimeGetCurrent() - start

Perlu dicatat bahwa CFAbsoluteTimeGetCurrentdokumentasi tersebut memperingatkan kita:

Panggilan berulang ke fungsi ini tidak menjamin hasil yang meningkat secara monoton. Waktu sistem dapat berkurang karena sinkronisasi dengan referensi waktu eksternal atau karena pengguna mengubah jam secara eksplisit.

Ini berarti bahwa jika Anda kurang beruntung untuk mengukur waktu yang berlalu ketika salah satu dari penyesuaian ini terjadi, Anda dapat berakhir dengan penghitungan waktu berlalu yang salah. Ini juga berlaku untuk NSDate/ Datekalkulasi. Paling aman menggunakan mach_absolute_timepenghitungan berbasis (paling mudah dilakukan dengan CACurrentMediaTime):

let start = CACurrentMediaTime()

dan

let elapsed = CACurrentMediaTime() - start

Ini menggunakan mach_absolute_time, tetapi menghindari beberapa kerumitan yang diuraikan dalam Tanya Jawab Teknis QA1398 .

Ingat, bagaimanapun, itu CACurrentMediaTime/ mach_absolute_timeakan diatur ulang ketika perangkat di-boot ulang. Jadi, intinya, jika Anda membutuhkan penghitungan waktu berlalu yang akurat saat aplikasi sedang berjalan, gunakan CACurrentMediaTime. Tetapi jika Anda akan menyimpan waktu mulai ini dalam penyimpanan persisten yang mungkin Anda ingat ketika aplikasi dimulai ulang di masa mendatang, maka Anda harus menggunakan Dateatau CFAbsoluteTimeGetCurrent, dan hidup dengan ketidakakuratan yang mungkin diperlukan.


4
Wow, terima kasih Rob! Jawaban Anda sangat membantu dan mudah dimengerti. Saya sangat menghargai tip tentang CFAbsoluteTime. Saya pasti akan menggunakan itu!
Erik

apa dimensi timeIntervalSinceDate?
eugene

Ia mengembalikan a TimeInterval, yang diukur dalam hitungan detik.
Rob

22

NSDate () dan NSCalendar () terdengar seperti pilihan yang bagus. Gunakan kalkulasi kalender dan serahkan bagian matematika yang sebenarnya ke kerangka. Berikut adalah contoh cepat untuk mendapatkan detik di antara duaNSDate()

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)")

Untuk beberapa alasan ini selalu mengembalikan 0 untuk saya meskipun tanggalnya berjarak satu jam.
Markymark

10

Menurut jawaban Freddy, inilah fungsi dalam 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
Terima kasih @LagMaster. Senang melihat swift menghilangkan awalan NS.
Freddy

4

Cepat 5

let differenceInSeconds = Int(endDate.timeIntervalSince(startDate))

0

Ini adalah bagaimana Anda bisa mendapatkan perbedaan di versi terbaru 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

Referensi: Mendapatkan perbedaan antara dua NSDates dalam (bulan / hari / jam / menit / detik)


-1

Cepat 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
Ini tidak memberikan perbedaan dalam detik dalam kode itu hanya kemudian apakah awal lebih besar atau tidak.
Arun K

-6

Untuk Swift 3 Detik antara 2 kali dalam "jj: 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

}

Pemakaian

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

Jawaban ini tidak relevan dengan jawaban op.
Tomasz Nazarenko
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.