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オブジェクトとして、指定された2つの日付の差を返します」。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;
floatをintに入れると、自動的にfloor()が取得されますが、気分が良ければ、最初の2つに追加することもできます:-)
スタックの処女であることを許して...ブライアンラムゼイの答えに返信する方法がわかりません...
ラウンドの使用は、59.5から59.99999の間の2番目の値に対しては機能しません。この間、2番目の値は60になります。代わりにtruncを使用してください...
double progress;
int minutes = floor(progress/60);
int seconds = trunc(progress - minutes * 60);
iOS 8またはOS X 10.10以上をターゲットにしている場合、これははるかに簡単になりました。新しいNSDateComponentsFormatter
クラスを使用すると、指定さNSTimeInterval
れた値を秒単位でローカライズされた文字列に変換して、ユーザーを表示できます。例えば:
Objective-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
、または2つのインスタンスを渡す方が便利な場合がありますNSDate
オブジェクトのます。これは、次のメソッドでも実行できます。
Objective-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
それをすべて処理します。時間、分、秒が心配なく印刷されます。
ブライアンラムゼイのコード、疑似偽装:
- (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"