Swift를 사용하여 NSDates를 정수로 초 단위로 차이 찾기


98

버튼을 누르고있는 시간을 측정하려는 코드를 작성하고 있습니다. 이를 위해 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를 몰라 주어진 답을 이해하는 데 어려움을 겪었습니다. 버튼을 누르고있는 시간을 더 효율적으로 확인할 수있는 방법이 있다면 제안을받을 수 있습니다. 미리 감사드립니다.

답변:


214

계산하려는 시도 elapsedTime가 잘못되었습니다. Swift 3에서는 다음과 같습니다.

let elapsed = Date().timeIntervalSince(timeAtPress)

참조 ()후 유의하십시오 Date. 는 Date()새 날짜 객체를 인스턴스화 한 다음 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가 재설정됩니다. 따라서 결론적으로 앱이 실행되는 동안 정확한 경과 시간 계산이 필요한 경우 CACurrentMediaTime. 그러나이 시작 시간을 영구 저장소에 저장하려는 경우 나중에 앱이 다시 시작될 때 기억할 수있는 경우에는 Date또는 을 사용해야 CFAbsoluteTimeGetCurrent하며 수반 될 수있는 모든 부정확성을 유지해야합니다.


4
와, 감사합니다 Rob! 귀하의 답변은 매우 유용하고 이해하기 쉬웠습니다. CFAbsoluteTime에 대한 팁에 정말 감사드립니다. 꼭 사용 할게요!
Erik

timeIntervalSinceDate의 차원은 무엇입니까?
유진 2015.11.10

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

10

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

4

스위프트 5

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

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
이것은 시작이 더 큰지 여부에 관계없이 코드에서 초 단위의 차이를 제공하지 않습니다.
Arun K

-6

"hh : mm"에서 2 시간 사이의 Swift 3 초 동안

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 2017
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.