objective-c 如何将 NSTimeInterval(秒)转换为分钟
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1189252/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert an NSTimeInterval (seconds) into minutes
提问by Ilya Suzdalnitski
I've got an amount of secondsthat passed from a certain event. It's stored in a NSTimeIntervaldata type.
我seconds从某个事件中获得了一定数量的传递。它存储在一种NSTimeInterval数据类型中。
I want to convert it into minutesand seconds.
我想把它转换成minutes和seconds。
For example I have: "326.4" seconds and I want to convert it into the following string: "5:26".
例如,我有:“326.4”秒,我想将其转换为以下字符串:“5:26”。
What is the best way to achieve this goal?
实现这一目标的最佳方法是什么?
Thanks.
谢谢。
回答by Albaregar
Brief Description
简要描述;简介
- The answer from Brian Ramsay is more convenient if you only want to convert to minutes.
- If you want Cocoa API do it for you and convert your NSTimeInterval not only to minutes but also to days, months, week, etc,... I think this is a more generic approach
Use NSCalendar method:
(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts"Returns, as an NSDateComponents object using specified components, the difference between two supplied dates". From the API documentation.
Create 2 NSDate whose difference is the NSTimeInterval you want to convert. (If your NSTimeInterval comes from comparing 2 NSDate you don't need to do this step, and you don't even need the NSTimeInterval).
Get your quotes from NSDateComponents
- 如果您只想转换为分钟,那么 Brian Ramsay 的答案会更方便。
- 如果你想让 Cocoa API 为你做这件事,并将你的 NSTimeInterval 不仅转换为分钟,还转换为天、月、周等,...我认为这是一种更通用的方法
使用 NSCalendar 方法:
(NSDateComponents *)components:(NSUInteger)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSUInteger)opts“返回,作为使用指定组件的 NSDateComponents 对象,两个提供的日期之间的差异”。来自 API 文档。
创建 2 个 NSDate,其不同之处在于您要转换的 NSTimeInterval。(如果你的 NSTimeInterval 来自比较 2 NSDate 你不需要做这一步,你甚至不需要 NSTimeInterval)。
从 NSDateComponents 获取您的报价
Sample Code
示例代码
// 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];
Known issues
已知的问题
- Too much for just a conversion, you are right, but that's how the API works.
- My suggestion: if you get used to manage your time data using NSDate and NSCalendar, the API will do the hard work for you.
- 只是转换太多了,你是对的,但这就是 API 的工作方式。
- 我的建议:如果您习惯于使用 NSDate 和 NSCalendar 管理时间数据,API 将为您完成繁重的工作。
回答by Brian Ramsay
pseudo-code:
伪代码:
minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)
回答by Prasad
All of these look more complicated than they need to be! Here is a short and sweet way to convert a time interval into hours, minutes and seconds:
所有这些看起来都比它们需要的更复杂!这是将时间间隔转换为小时、分钟和秒的简短而甜蜜的方法:
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;
Note when you put a float into an int, you get floor() automatically, but you can add it to the first two if if makes you feel better :-)
请注意,当您将浮点数放入 int 时,您会自动获得 floor(),但如果让您感觉更好,您可以将其添加到前两个中 :-)
回答by StratFan
Forgive me for being a Stack virgin... I'm not sure how to reply to Brian Ramsay's answer...
原谅我是 Stack 处女......我不知道如何回复 Brian Ramsay 的回答......
Using round will not work for second values between 59.5 and 59.99999. The second value will be 60 during this period. Use trunc instead...
使用 round 不适用于 59.5 和 59.99999 之间的第二个值。在此期间,第二个值将为 60。使用 trunc 代替...
double progress;
int minutes = floor(progress/60);
int seconds = trunc(progress - minutes * 60);
回答by Mick MacCallum
If you're targeting at or above iOS 8 or OS X 10.10, this just got a lot easier. The new NSDateComponentsFormatterclass allows you to convert a given NSTimeIntervalfrom its value in seconds to a localized string to show the user. For example:
如果您的目标是 iOS 8 或 OS X 10.10 或更高版本,这将变得容易得多。新NSDateComponentsFormatter类允许您以NSTimeInterval秒为单位将给定值从其值转换为本地化字符串以显示给用户。例如:
Objective-C
目标-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
Swift
迅速
let interval = 326.4
let componentFormatter = NSDateComponentsFormatter()
componentFormatter.unitsStyle = .Positional
componentFormatter.zeroFormattingBehavior = .DropAll
if let formattedString = componentFormatter.stringFromTimeInterval(interval) {
print(formattedString) // 5:26
}
NSDateCompnentsFormatteralso allows for this output to be in longer forms. More info can be found in NSHipster's NSFormatter article. And depending on what classes you're already working with (if not NSTimeInterval), it may be more convenient to pass the formatter an instance of NSDateComponents, or two NSDateobjects, which can be done as well via the following methods.
NSDateCompnentsFormatter还允许此输出采用更长的形式。更多信息可以在 NSHipster 的NSFormatter 文章中找到。并且根据您已经使用的类(如果没有NSTimeInterval),向格式化程序传递一个NSDateComponents或两个NSDate对象的实例可能更方便,这也可以通过以下方法完成。
Objective-C
目标-C
NSString *formattedString = [componentFormatter stringFromDate:<#(NSDate *)#> toDate:<#(NSDate *)#>];
NSString *formattedString = [componentFormatter stringFromDateComponents:<#(NSDateComponents *)#>];
Swift
迅速
if let formattedString = componentFormatter.stringFromDate(<#T##startDate: NSDate##NSDate#>, toDate: <#T##NSDate#>) {
// ...
}
if let formattedString = componentFormatter.stringFromDateComponents(<#T##components: NSDateComponents##NSDateComponents#>) {
// ...
}
回答by Yang Meyer
Brian Ramsay's code, de-pseudofied:
布赖恩拉姆齐的代码,去伪:
- (NSString*)formattedStringForDuration:(NSTimeInterval)duration
{
NSInteger minutes = floor(duration/60);
NSInteger seconds = round(duration - minutes * 60);
return [NSString stringWithFormat:@"%d:%02d", minutes, seconds];
}
回答by Jochen Bedersdorfer
Here's a Swift version:
这是一个 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)
}
Can be used like this:
可以这样使用:
let (d,h,m,s) = durationsBySecond(seconds: duration)
println("time left: \(d) days \(h) hours \(m) minutes \(s) seconds")
回答by polarware
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);
Outputs:
输出:
timeLater: 22:27
timeLeft: 1 hours 29 minutes 59 seconds
回答by polarware
Since it's essentially a double...
因为它本质上是一个双...
Divide by 60.0 and extract the integral part and the fractional part.
除以 60.0 并提取整数部分和小数部分。
The integral part will be the whole number of minutes.
整数部分将是分钟数。
Multiply the fractional part by 60.0 again.
再次将小数部分乘以 60.0。
The result will be the remaining seconds.
结果将是剩余的秒数。
回答by SwiftArchitect
Remember that the original question is about a string output, not pseudo-code or individual string components.
请记住,最初的问题是关于字符串输出,而不是伪代码或单个字符串组件。
I want to convert it into the following string: "5:26"
我想将其转换为以下字符串:“5:26”
Many answers are missing the internationalization issues, and most doing the math computations by hand. All just so 20th century...
许多答案都忽略了国际化问题,而且大多数答案都是手工进行的数学计算。就这样20世纪...
Do not do the Math yourself (Swift 4)
不要自己做数学(Swift 4)
let timeInterval: TimeInterval = 326.4
let dateComponentsFormatter = DateComponentsFormatter()
dateComponentsFormatter.unitsStyle = .positional
if let formatted = dateComponentsFormatter.string(from: timeInterval) {
print(formatted)
}
5:26
5:26
Leverage on libraries
利用图书馆
If you really want individual components, and pleasantly readable code, check out SwiftDate:
如果你真的想要单独的组件和可读的代码,请查看SwiftDate:
import SwiftDate
...
if let minutes = Int(timeInterval).seconds.in(.minute) {
print("\(minutes)")
}
5
5
Credits to @mickmaccallumand @polarwarfor adequate usage of DateComponentsFormatter
感谢@mickmaccallum和@polarwar充分使用DateComponentsFormatter

