seconds
특정 이벤트에서 전달 된 금액이 있습니다. NSTimeInterval
데이터 유형에 저장됩니다 .
나는 그것을 minutes
및 로 변환하고 싶습니다 seconds
.
예를 들어 "326.4"초가 있고 "5:26"문자열로 변환하고 싶습니다.
이 목표를 달성하는 가장 좋은 방법은 무엇입니까?
감사.
seconds
특정 이벤트에서 전달 된 금액이 있습니다. NSTimeInterval
데이터 유형에 저장됩니다 .
나는 그것을 minutes
및 로 변환하고 싶습니다 seconds
.
예를 들어 "326.4"초가 있고 "5:26"문자열로 변환하고 싶습니다.
이 목표를 달성하는 가장 좋은 방법은 무엇입니까?
감사.
답변:
의사 코드 :
minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)
간단한 설명
NSCalendar 방법 사용 :
(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts
"지정된 구성 요소를 사용하는 NSDateComponents 개체로 제공된 두 날짜 간의 차이를 반환합니다." API 문서에서.
변환하려는 NSTimeInterval과 차이가있는 2 개의 NSDate를 만듭니다. (NSTimeInterval이 2 개의 NSDate를 비교하는 것에서 나온다면이 단계를 수행 할 필요가 없으며 NSTimeInterval도 필요하지 않습니다).
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];
알려진 문제
%ld
64 비트 머신을 사용하는 경우.
이 모든 것들은 필요 이상으로 복잡해 보입니다! 다음은 시간 간격을 시간, 분 및 초로 변환하는 짧고 유용한 방법입니다.
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#>) {
// ...
}
switch
또는 if else
진술이 필요하지 않습니다 . NSDateComponentsFormatter
모든 것을 처리합니다. 시간, 분, 초가 걱정없이 인쇄됩니다.
위장 된 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")
NSDate *timeLater = [NSDate dateWithTimeIntervalSinceNow:60*90];
NSTimeInterval duration = [timeLater timeIntervalSinceNow];
NSInteger hours = floor(duration/(60*60));
NSInteger minutes = floor((duration/60) - hours * 60);
NSInteger seconds = floor(duration - (minutes * 60) - (hours * 60 * 60));
NSLog(@"timeLater: %@", [dateFormatter stringFromDate:timeLater]);
NSLog(@"time left: %d hours %d minutes %d seconds", hours,minutes,seconds);
출력 :
timeLater: 22:27
timeLeft: 1 hours 29 minutes 59 seconds
본질적으로 이중이기 때문에 ...
60.0으로 나누고 적분 부분과 분수 부분을 추출합니다.
정수 부분은 전체 분입니다.
분수 부분에 다시 60.0을 곱합니다.
결과는 남은 시간 (초)입니다.
원래 질문은 의사 코드 나 개별 문자열 구성 요소가 아니라 문자열 출력에 관한 것임을 기억하십시오.
다음 문자열로 변환하고 싶습니다 : "5:26"
많은 답변에 국제화 문제가 누락되어 있으며 대부분은 수작업으로 수학 계산을 수행합니다. 20 세기 만해도 ...
let timeInterval: TimeInterval = 326.4
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.unitsStyle = .positional
if let formatted = dateComponentsFormatter.string(from: timeInterval) {
print(formatted)
}
5:26
개별 구성 요소와 읽기 쉬운 코드를 정말로 원한다면 SwiftDate를 확인하십시오 .
import SwiftDate
...
if let minutes = Int(timeInterval).seconds.in(.minute) {
print("\(minutes)")
}
5
적절한 사용을 위해 @mickmaccallum 및 @polarwar에 대한 크레딧DateComponentsFormatter
Swift에서 어떻게했는지 ( "01:23"로 표시하는 문자열 형식 포함) :
let totalSeconds: Double = someTimeInterval
let minutes = Int(floor(totalSeconds / 60))
let seconds = Int(round(totalSeconds % 60))
let timeString = String(format: "%02d:%02d", minutes, seconds)
NSLog(timeString)
Swift 2 버전
extension NSTimeInterval {
func toMM_SS() -> String {
let interval = self
let componentFormatter = NSDateComponentsFormatter()
componentFormatter.unitsStyle = .Positional
componentFormatter.zeroFormattingBehavior = .Pad
componentFormatter.allowedUnits = [.Minute, .Second]
return componentFormatter.stringFromTimeInterval(interval) ?? ""
}
}
let duration = 326.4.toMM_SS()
print(duration) //"5:26"