105

seconds从某个事件中获得了一定数量的传递。它存储在NSTimeInterval数据类型中。

我想把它转换成minutesand seconds

例如,我有:“326.4”秒,我想将其转换为以下字符串:“5:26”。

实现这一目标的最佳方法是什么?

谢谢。

4

12 回答 12

183

简要描述;简介

  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. 创建 2 个 NSDate,其差异是您要转换的 NSTimeInterval。(如果您的 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 将为你完成艰苦的工作。
于 2009-09-06T17:27:07.530 回答
147

伪代码:

minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)
于 2009-07-27T16:42:36.593 回答
43

所有这些看起来都比他们需要的更复杂!这是将时间间隔转换为小时、分钟和秒的一种简短而实用的方法:

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 时,您会自动获得 floor(),但如果让您感觉更好,您可以将其添加到前两个 :-)

于 2013-03-08T23:04:32.660 回答
29

原谅我是 Stack 处女……我不知道如何回复 Brian Ramsay 的回答……

对于介于 59.5 和 59.99999 之间的第二个值,使用 round 无效。在此期间,第二个值将是 60。改用 trunc ...

 double progress;

 int minutes = floor(progress/60);
 int seconds = trunc(progress - minutes * 60);
于 2010-11-12T21:39:19.063 回答
27

如果您的目标是 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的实例可能更方便,这也可以通过以下方法完成。NSDateComponentsNSDate

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#>) {
    // ...
}
于 2015-01-31T13:59:03.617 回答
17

布赖恩拉姆齐的代码,去伪:

- (NSString*)formattedStringForDuration:(NSTimeInterval)duration
{
    NSInteger minutes = floor(duration/60);
    NSInteger seconds = round(duration - minutes * 60);
    return [NSString stringWithFormat:@"%d:%02d", minutes, seconds];
}
于 2012-09-27T15:32:09.387 回答
7

这是一个 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")
于 2014-09-22T06:04:17.737 回答
6
    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
于 2014-01-25T20:03:05.510 回答
5

因为它本质上是一个双...

除以 60.0 并提取整数部分和小数部分。

整数部分将是分钟的整数。

再次将小数部分乘以 60.0。

结果将是剩余的秒数。

于 2009-07-27T16:49:38.017 回答
3

请记住,最初的问题是关于字符串输出,而不是伪代码或单个字符串组件。

我想将其转换为以下字符串:“5:26”

许多答案都缺少国际化问题,并且大多数是手工进行数学计算。一切都只是20世纪...

不要自己做数学(Swift 4)

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

于 2017-10-10T19:13:20.560 回答
0

我是如何在 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)
于 2016-07-04T20:51:39.700 回答
0

斯威夫特 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"
于 2017-04-12T05:29:04.677 回答