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

Ily*_*ski 104 iphone objective-c minute seconds nstimeinterval

我从某个事件中获得了一定的秒数.它存储在NSTimeInterval数据类型中.

我想把它转换成分钟和秒.

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

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

谢谢.

小智 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];
Run Code Online (Sandbox Code Playgroud)

已知的问题

  • 对于转换来说太多了,你是对的,但这就是API的工作原理.
  • 我的建议是:如果您习惯使用NSDate和NSCalendar来管理您的时间数据,那么API将为您完成艰苦的工作.

  • 找到这个的人(比如Nick Weaver)会认为代码看起来会很慢.事实并非如此.我正在做一个计时器应用程序,我刚刚测试了Albaregar的版本,反对布莱恩拉姆齐(以及其他人)的风格...而且令人惊讶的是,甚至在相对较慢的设备(4S)上每秒轮询100次(这是极大的矫枉过正) )处理器利用率差异不到1%. (5认同)
  • 确切地说,只需进行一点转换就可以解决很多问题,但它感觉舒适,模块化且非常灵活,可以为这个示例代码@Albaregar投票. (4认同)
  • +1为了得到一个很好的彻底答案,但是这段代码非常昂贵. (2认同)

Bri*_*say 146

伪代码:

minutes = floor(326.4/60)
seconds = round(326.4 - minutes * 60)
Run Code Online (Sandbox Code Playgroud)

  • 我认为值得一提的是NSTimerInterval只是double的typedef. (89认同)
  • 请参阅Albaregar的答案 - 这是一种更好的方法(更多代码,但更灵活,可维护) (4认同)
  • 请注意,这个答案将为您提供像1:60这样的东西.看看StratFan的回答更贴近事实.但删除地板和圆形,你应该在家里免费. (2认同)

小智 42

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

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;
Run Code Online (Sandbox Code Playgroud)

注意当你把一个浮点数放到一个int中时,你会自动得到floor(),但如果让你感觉更好,你可以把它添加到前两个:-)


小智 29

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

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

 double progress;

 int minutes = floor(progress/60);
 int seconds = trunc(progress - minutes * 60);
Run Code Online (Sandbox Code Playgroud)


Mic*_*lum 26

如果你的目标是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
Run Code Online (Sandbox Code Playgroud)

迅速

let interval = 326.4

let componentFormatter = NSDateComponentsFormatter()

componentFormatter.unitsStyle = .Positional
componentFormatter.zeroFormattingBehavior = .DropAll

if let formattedString = componentFormatter.stringFromTimeInterval(interval) {
    print(formattedString) // 5:26
}
Run Code Online (Sandbox Code Playgroud)

NSDateCompnentsFormatter也允许此输出为更长的形式.更多信息可以在NSHipster的NSFormatter文章中找到.根据您正在使用的类(如果没有NSTimeInterval),将格式化程序传递给一个实例NSDateComponents或两个NSDate对象可能更方便,这也可以通过以下方法完成.

Objective-C的

NSString *formattedString = [componentFormatter stringFromDate:<#(NSDate *)#> toDate:<#(NSDate *)#>];
NSString *formattedString = [componentFormatter stringFromDateComponents:<#(NSDateComponents *)#>];
Run Code Online (Sandbox Code Playgroud)

迅速

if let formattedString = componentFormatter.stringFromDate(<#T##startDate: NSDate##NSDate#>, toDate: <#T##NSDate#>) {
    // ...
}

if let formattedString = componentFormatter.stringFromDateComponents(<#T##components: NSDateComponents##NSDateComponents#>) {
    // ...
}
Run Code Online (Sandbox Code Playgroud)


Yan*_*yer 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];
}
Run Code Online (Sandbox Code Playgroud)


Joc*_*fer 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)
}
Run Code Online (Sandbox Code Playgroud)

可以像这样使用:

let (d,h,m,s) = durationsBySecond(seconds: duration)
println("time left: \(d) days \(h) hours \(m) minutes \(s) seconds")
Run Code Online (Sandbox Code Playgroud)


pol*_*war 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);
Run Code Online (Sandbox Code Playgroud)

输出:

timeLater: 22:27
timeLeft: 1 hours 29 minutes  59 seconds
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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

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

再次将小数部分乘以60.0.

结果将是剩余的秒数.