[objective-c] NSTimeInterval (초)을 분으로 변환하는 방법

seconds특정 이벤트에서 전달 된 금액이 있습니다. NSTimeInterval데이터 유형에 저장됩니다 .

나는 그것을 minutes및 로 변환하고 싶습니다 seconds.

예를 들어 “326.4”초가 있고 “5:26″문자열로 변환하고 싶습니다.

이 목표를 달성하는 가장 좋은 방법은 무엇입니까?

감사.



답변

의사 코드 :

minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)


답변

간단한 설명

  1. Brian Ramsay의 대답은 분 단위로만 변환하려는 경우 더 편리합니다.
  2. Cocoa API를 원하면 NSTimeInterval을 분뿐만 아니라 일, 월, 주 등으로 변환하십시오. 이것은 좀 더 일반적인 접근 방식이라고 생각합니다.
  3. NSCalendar 방법 사용 :

    • (NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts

    • “지정된 구성 요소를 사용하는 NSDateComponents 개체로 제공된 두 날짜 간의 차이를 반환합니다.” API 문서에서.

  4. 변환하려는 NSTimeInterval과 차이가있는 2 개의 NSDate를 만듭니다. (NSTimeInterval이 2 개의 NSDate를 비교하는 것에서 나온다면이 단계를 수행 할 필요가 없으며 NSTimeInterval도 필요하지 않습니다).

  5. NSDateComponents에서 견적 받기

샘플 코드

// The time interval 
NSTimeInterval theTimeInterval = 326.4;

// Get the system calendar
NSCalendar *sysCalendar = [NSCalendar currentCalendar];

// Create the NSDates
NSDate *date1 = [[NSDate alloc] init];
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:theTimeInterval sinceDate:date1];

// Get conversion to months, days, hours, minutes
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit;

NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:date1  toDate:date2  options:0];

NSLog(@"Conversion: %dmin %dhours %ddays %dmoths",[conversionInfo minute], [conversionInfo hour], [conversionInfo day], [conversionInfo month]);

[date1 release];
[date2 release];

알려진 문제

  • 전환에 너무 많은 것은 맞지만 API가 작동하는 방식입니다.
  • 내 제안 : NSDate 및 NSCalendar를 사용하여 시간 데이터를 관리하는 데 익숙해지면 API가 열심히 일할 것입니다.

답변

이 모든 것들은 필요 이상으로 복잡해 보입니다! 다음은 시간 간격을 시간, 분 및 초로 변환하는 짧고 유용한 방법입니다.

NSTimeInterval timeInterval = 326.4;
long seconds = lroundf(timeInterval); // Since modulo operator (%) below needs int or long

int hour = seconds / 3600;
int mins = (seconds % 3600) / 60;
int secs = seconds % 60;

int에 float를 넣으면 자동으로 floor ()를 얻지 만 기분이 나아지면 처음 두 개에 추가 할 수 있습니다. 🙂


답변

스택 처녀가 된 것을 용서하십시오 … Brian Ramsay의 답변에 어떻게 대답 해야할지 모르겠습니다 …

라운드를 사용하면 59.5에서 59.99999 사이의 두 번째 값에 대해 작동하지 않습니다. 이 기간 동안 두 번째 값은 60이됩니다. 대신 trunc 사용 …

 double progress;

 int minutes = floor(progress/60);
 int seconds = trunc(progress - minutes * 60);


답변

iOS 8 또는 OS X 10.10 이상을 타겟팅하는 경우 훨씬 쉬워졌습니다. 새 NSDateComponentsFormatter클래스를 사용하면 주어진 NSTimeInterval값을 초 단위로 현지화 된 문자열 로 변환 하여 사용자에게 표시 할 수 있습니다. 예를 들면 :

목표 -C

NSTimeInterval interval = 326.4;

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

componentFormatter.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
componentFormatter.zeroFormattingBehavior = NSDateComponentsFormatterZeroFormattingBehaviorDropAll;

NSString *formattedString = [componentFormatter stringFromTimeInterval:interval];
NSLog(@"%@",formattedString); // 5:26

빠른

let interval = 326.4

let componentFormatter = NSDateComponentsFormatter()

componentFormatter.unitsStyle = .Positional
componentFormatter.zeroFormattingBehavior = .DropAll

if let formattedString = componentFormatter.stringFromTimeInterval(interval) {
    print(formattedString) // 5:26
}

NSDateCompnentsFormatter또한이 출력이 더 긴 형식이 될 수 있습니다. 더 많은 정보는 NSHipster의 NSFormatter 기사 에서 찾을 수 있습니다 . 그리고 이미 작업중인 클래스에 따라 (그렇지 않은 경우 NSTimeInterval) 포맷터에의 인스턴스 NSDateComponents또는 두 개의 NSDate개체 를 전달하는 것이 더 편리 할 수 있습니다. 다음 메서드를 통해서도 수행 할 수 있습니다.

목표 -C

NSString *formattedString = [componentFormatter stringFromDate:<#(NSDate *)#> toDate:<#(NSDate *)#>];
NSString *formattedString = [componentFormatter stringFromDateComponents:<#(NSDateComponents *)#>];

빠른

if let formattedString = componentFormatter.stringFromDate(<#T##startDate: NSDate##NSDate#>, toDate: <#T##NSDate#>) {
    // ...
}

if let formattedString = componentFormatter.stringFromDateComponents(<#T##components: NSDateComponents##NSDateComponents#>) {
    // ...
}


답변

위장 된 Brian Ramsay의 코드 :

- (NSString*)formattedStringForDuration:(NSTimeInterval)duration
{
    NSInteger minutes = floor(duration/60);
    NSInteger seconds = round(duration - minutes * 60);
    return [NSString stringWithFormat:@"%d:%02d", minutes, seconds];
}


답변

다음은 Swift 버전입니다.

func durationsBySecond(seconds s: Int) -> (days:Int,hours:Int,minutes:Int,seconds:Int) {
    return (s / (24 * 3600),(s % (24 * 3600)) / 3600, s % 3600 / 60, s % 60)
}

다음과 같이 사용할 수 있습니다.

let (d,h,m,s) = durationsBySecond(seconds: duration)
println("time left: \(d) days \(h) hours \(m) minutes \(s) seconds")