如何将NSTimeInterval(秒)转换为分钟

时间:2009-07-27 16:39:56

标签: objective-c iphone nstimeinterval seconds minute

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

我想将其转换为minutesseconds

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

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

感谢。

12 个答案:

答案 0 :(得分:182)

简要说明

  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

  6. 获取报价

    示例代码

    // 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将为您付出艰苦的努力。

答案 1 :(得分:146)

伪码:

minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)

答案 2 :(得分:41)

所有这些看起来都比他们需要的更复杂!以下是将时间间隔转换为小时,分钟和秒的简短而甜蜜的方法:

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(),但是如果你觉得更好的话可以把它添加到前两个: - )

答案 3 :(得分:29)

原谅我是一个Stack处女......我不知道如何回答Brian Ramsay的回答......

使用round将不适用于59.5和59.99999之间的第二个值。在此期间,第二个值为60。请改用trunc ...

 double progress;

 int minutes = floor(progress/60);
 int seconds = trunc(progress - minutes * 60);

答案 4 :(得分:26)

如果你的目标是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 article中找到。根据您正在使用的类(如果不是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#>) {
    // ...
}

答案 5 :(得分:17)

Brian Ramsay的代码,de-pseudofied:

- (NSString*)formattedStringForDuration:(NSTimeInterval)duration
{
    NSInteger minutes = floor(duration/60);
    NSInteger seconds = round(duration - minutes * 60);
    return [NSString stringWithFormat:@"%d:%02d", minutes, seconds];
}

答案 6 :(得分:8)

这是一个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")

答案 7 :(得分: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

答案 8 :(得分:5)

因为它基本上是双重的......

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

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

再次将小数部分乘以60.0。

结果将是剩余的秒数。

答案 9 :(得分:3)

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

  

我想将其转换为以下字符串:&#34; 5:26&#34;

许多答案都缺少国际化问题,大多数答案都是手工进行数学计算。所有这些都是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

答案 10 :(得分:0)

我是如何在Swift中执行此操作的(包括字符串格式将其显示为&#34; 01:23&#34;):

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)

答案 11 :(得分:0)

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"