我有一个记录了某个事件经过的秒数的变量,它是以NSTimeInterval
数据类型存储的。
我想将它转换成分钟
和秒
的形式。
例如,如果我有: "326.4"秒,我想将其转换为以下字符串:“5:26”。
实现这个目标的最佳方法是什么?
谢谢。
我有一个记录了某个事件经过的秒数的变量,它是以NSTimeInterval
数据类型存储的。
我想将它转换成分钟
和秒
的形式。
例如,如果我有: "326.4"秒,我想将其转换为以下字符串:“5:26”。
实现这个目标的最佳方法是什么?
谢谢。
简要说明
使用NSCalendar方法:
(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts
"使用指定的组件,返回两个提供的日期之间的差异作为NSDateComponents对象"。来自API文档。
创建两个NSDate,它们的差值是你想要转换的NSTimeInterval。(如果你的NSTimeInterval来自比较两个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];
已知问题
伪代码:
minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)
所有这些看起来都比必要的复杂!这里有一种简单明了的方法将时间间隔转换为小时、分钟和秒:
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;
注意将浮点数转换成整数时,会自动执行 floor() 函数,但如果你感觉更好,可以将其添加到前两个整数中。
请原谅我是一个Stack的新手...我不确定如何回复Brian Ramsay的答案...
使用round对于59.5到59.99999之间的秒值将无效。在这段时间内,秒值将为60。改用trunc...
double progress;
int minutes = floor(progress/60);
int seconds = trunc(progress - minutes * 60);
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
对象传递给格式化程序可能更方便。
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
会为你处理一切。小时,分钟,秒钟都可以轻松输出,无需担心。 - rustyMagnetBrian Ramsay的代码,去伪存真:
- (NSString*)formattedStringForDuration:(NSTimeInterval)duration
{
NSInteger minutes = floor(duration/60);
NSInteger seconds = round(duration - minutes * 60);
return [NSString stringWithFormat:@"%d:%02d", minutes, seconds];
}
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
的充分使用。
%ld
。 - Anoop Vaidya