NSTimeInterval to HH : mm : ss?


85

200.0으로 설정된 NSTimeInterval이 있으면이를 00:03:20으로 변환하는 방법이 있습니까? NSDate를 초기화 한 다음 HH : mm : ss를 사용하여 NSDateFormatter를 사용할 수 있다고 생각했습니다. 내 질문은 이것을 수행하는 빠른 방법이 [NSString stringWithFormat: %02d:%02d:%02d, myHour, myMin, mySec]있습니까? 아니면 직접 번호를 나누고 사용해야 합니까?

답변:


198

NSDateFormatter나눗셈과 모듈로 외에는 사용할 필요가 없습니다 . NSTimeInterval초를 포함하는 두 배입니다.

빠른

func stringFromTimeInterval(interval: NSTimeInterval) -> String {
    let interval = Int(interval)
    let seconds = interval % 60
    let minutes = (interval / 60) % 60
    let hours = (interval / 3600)
    return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
}

목표 -C

- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {
    NSInteger ti = (NSInteger)interval;
    NSInteger seconds = ti % 60;
    NSInteger minutes = (ti / 60) % 60;
    NSInteger hours = (ti / 3600);
    return [NSString stringWithFormat:@"%02ld:%02ld:%02ld", (long)hours, (long)minutes, (long)seconds];
}

그게 제가 생각했던 것입니다.하지만 이미 iOS SDK의 일부로 포함 된 것이 누락되지 않았는지 확인하고 싶었습니다.
fuzzygoat 2013

1
":"는 영어와 다른 언어에서만 구분 기호로 작동한다는 점을 지적하고 싶습니다. 예를 들어 핀란드어는 "."를 사용합니다. - "15.02.59"처럼
sgosha

@sgosha, 정확히, 일반적으로 Apple은 이러한 포맷터를 제공하는 경향이 있습니다. 대신 현지화 된 문자열을 형식화에 사용해야합니까?
Gerry Shaw

20
다른 주석에서 언급했듯이 구분 기호를 지역화하지 않기 때문에 이것은 잘못된 대답입니다. NSDateCompomentsFormatter를 사용하면 시간 간격을 한 줄로 올바르게 포맷 할 수 있습니다. 예를 들어 NSDateComponentsFormatter().stringFromTimeInterval(NSTimeInterval(duration))swift
Ilias Karim

4
현지화 및 향후 교정을 위해 올바른 해결책은 @jrc
voidref

102

iOS 8에서는 NSDateComponentsFormatter.

NSDateComponentsFormatter *dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init];
NSLog(@"%@", [dateComponentsFormatter stringFromTimeInterval:200.0]);

"3:20"을 출력합니다.

NSDateComponentsFormatter *dateComponentsFormatter = [[NSDateComponentsFormatter alloc] init];
dateComponentsFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;
dateComponentsFormatter.allowedUnits = (NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond);
NSLog(@"%@", [dateComponentsFormatter stringFromTimeInterval:200.0]);

"0:03:20"을 출력합니다.


2
멋진 업데이트입니다. 하지만 정말 단순한 계산이라면이 객체를 사용하여 엄청난 오버 헤드를 일으키지 않을까요 (동적 형식이 관련되지 않는 한)?
Julian F. Weinert

2
당신은 문자열 등 로케일 다른 올바르게 표시하기 위해 포맷을해야합니다
최대 MacLeod는

아주 작은 주석이지만 ObjectiveC 질문에 대한 C 함수의 예를 제공하는 것은 이상합니다. 아마도 ObjectiveC 형식으로 변경할 가치가 있습니까?
Rilakkuma

엄청난 양의 코드를 절약했습니다! 이것이 내가 OrangeIRC에 사용한 방법 입니다.
ahyattdev

17

onmyway133 의 답변 의 Swift 3 버전 :

import Foundation

func format(_ duration: TimeInterval) -> String {
    let formatter = DateComponentsFormatter()
    formatter.zeroFormattingBehavior = .pad
    formatter.allowedUnits = [.minute, .second]

    if duration >= 3600 {
        formatter.allowedUnits.insert(.hour)
    }

    return formatter.string(from: duration)!
}


print(format(12)) // 0:12
print(format(65)) // 1:05
print(format(1750)) // 29:10
print(format(3890)) // 1:04:50
print(format(45720)) // 12:42:00

DateFormatter 또는 NumberFormatter와 같이 DateComponentsFormatter를 만드는 데 성능면에서 비용이 많이 듭니까?
Moshe

1
시간 값이 있는지 확인하는 대신 zeroFormattingBehaviorbe로 설정 하는 것이 [.dropLeading, .pad]더 나은 (더 적은 코드) 옵션 일 수 있습니다.
MaddTheSane 2010 년

설명이 잘못된 것 같습니다. 이 코드 결과 : 00:12, 01:05, 29:10, 01:04:50, 12:42:00
Jordan H

10

추가 코드 줄이 있지만 NSDateComponents를 사용하면 더 정확한 값을 얻을 수 있습니다.

- (NSString *)getTimeRepresentationFromDate:(NSDate *)iDate withTimeInterval:(NSTimeInterval)iTimeInterval {
    NSString *aReturnValue = nil;
    NSDate *aNewDate = [iDate dateByAddingTimeInterval:iTimeInterval]; 

    unsigned int theUnits = NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    NSCalendar *aCalender = [NSCalendar currentCalendar];
    NSDateComponents *aDateComponents = [aCalender components:theUnits fromDate:iDate toDate:aNewDate options:0];

    aReturnValue = [NSString stringWithFormat:@"%d:%d:%d", [aDateComponents hour], [aDateComponents minute], [aDateComponents second]];

    return aReturnValue;
}

위의 방법은 TimeInterval이 생성되는 2 개의 날짜를 사용합니다. [NSDate date]를 iDate 매개 변수에 기본값으로 전달할 수도 있습니다.
Roshit

2
@ matthias-bauch가 사용하는 방법보다이 방법이 어떤면에서 "더 정확"합니까?
jb

1
이 방법을 사용하면 시간 간격을 초, 시간, 분 단위로 얻습니다. 즉, 60의 관점에서 @ matthias-bauch의 답변은 십진수로 제공합니다. 예를 들어 충분한 시간을 기다리면 2 분 19 초 대신 1 분 79 초가 표시됩니다.
Ashish Pisey 2014 년

이것은 허용 된 솔루션보다 훨씬 더 나은 솔루션입니다. ":"의 사용은 여전히 ​​국제화에 문제가되지만 적어도 윤일과 일광 절약 경계를 넘어 강력합니다.
evanflash 2014 년

59 이상의 모듈로 연산자 방지 아무것도 더 큰 @AshishPisey
마티아스 Bauch

8

에서 스위프트 2 , 아이폰 OS 8 이상 . 이렇게하면 필요할 때만 시간이 표시됩니다.

func format(duration: NSTimeInterval) -> String {
  let formatter = NSDateComponentsFormatter()
  formatter.zeroFormattingBehavior = .Pad

  if duration >= 3600 {
    formatter.allowedUnits = [.Hour, .Minute, .Second]
  } else {
    formatter.allowedUnits = [.Minute, .Second]
  }

  return formatter.stringFromTimeInterval(duration) ?? ""
}

그래서 당신은

print(format(12)) // 0:12
print(format(65)) // 1:05
print(format(1750)) // 29:10
print(format(3890)) // 1:04:50
print(format(45720)) // 12:42:00

4
NSTimeInterval ti = 3667;
double hours = floor(ti / 60 / 60);
double minutes = floor((ti - (hours * 60 * 60)) / 60);
double seconds = floor(ti - (hours * 60 * 60) - (minutes * 60));

4

스위프트 4

DateComponentsFormatter().string(from: <# TimeInterval #>)

전의:

DateComponentsFormatter().string(from: 59.0)

3

Matthias Bauch의 제안을 "확장"하기 위해 Swift에서 나는 이것을 NSTimeInterval의 계산 된 속성으로 만들 것입니다.

extension NSTimeInterval {
  var stringValue: String {
    let interval = Int(self)
    let seconds = interval % 60
    let minutes = (interval / 60) % 60
    let hours = (interval / 3600)
    return String(format: "%02d:%02d:%02d", hours, minutes, seconds)
  }
}

이것의 장점은 NSTimeInterval뷰 컨트롤러가 아닌 유형에 연결되어 있거나 해당 기능을 배치하는 곳에 연결된다는 것입니다. 사용하려면 다음과 같이 가십시오.

let timeInterval = NSDate().timeIntervalSinceDate(start)        
self.elapsedTimeLabel.text = timeInterval.stringValue

고마워, 케니! 필자의 경우에는 별도로 필요 했으므로 확장에 추가 변수를 추가했습니다. "var seconds : Int {let interval = Int (self); let seconds = interval % 60; return seconds}"등등. 따라서 사용량은 다음과 같습니다. print ( "소요 시간 : (timeInterval.minutes)")
Vitalii

3

@ onmyway133의 답변에 따라 Swift 4 버전은 다음과 같습니다.

func format(duration: TimeInterval) -> String {
    let formatter = DateComponentsFormatter()
    formatter.zeroFormattingBehavior = .pad

    if duration >= 3600 {
        formatter.allowedUnits = [.hour, .minute, .second];
    } else {
        formatter.allowedUnits = [.minute, .second];
    }

    return formatter.string(from: duration) ?? "";
}

0

애플 문서에서 바로 : h 파일에서 :

 @property(strong,nonatomic)NSDateComponentsFormatter *timerFormatter;

m 파일에서

@synthesize timerFormatter;

- (void)viewDidLoad {
[super viewDidLoad];
NSDateComponentsFormatter *timerFormatter = [[NSDateComponentsFormatter alloc] init];
timerFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional; 
//10:59 Positional THIS ONE DOES NOT SEEM TO WORK iOS<9 WHEN <1Minute JUST SHOWS 01, 10m 59s Abbreviated, 10min 59sec Short, 10minutes 59seconds Full ...
timerFormatter.allowedUnits = NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond;
}

NSTimeInterval timeInterval을 hh : mm : ss 문자열로 변환해야 할 때마다 다음을 수행하십시오.

NSString *txt=[timerFormatter stringFromTimeInterval:timeInterval];

0

나는 타이머 분수가 중단되어야한다고 생각한다. Matthias의 코드가이 문제를 몇 초 만에 생성했기 때문에 Matthias의 코드에서 약간 수정 된 다음을 사용합니다.

    - (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {
        int ti = (int) ceil(interval);
        int seconds = ti % 60;
        int minutes = (ti / 60) % 60;
        int hours = (ti / 3600);
        return [NSString stringWithFormat:@"%02d:%02d:%02d",hours, minutes, seconds];
    }

0

onmyway133의 대답 목표 C 버전

- (NSString*) formatTimeInterval:(NSTimeInterval) timeInterval {

    NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];

    formatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorPad;

    if (timeInterval > 3600) {
        formatter.allowedUnits = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    } else {
        formatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitSecond;
    }

    return [formatter stringFromTimeInterval:timeInterval];
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.