如何在swift中格式化用户显示(社交网络)的时间间隔?

我有一个时间间隔,比如12600,相当于3小时30分钟。 我如何格式化任何这样的时间间隔,以便只保留间隔的最高部分(例如在这种情况下图中的小时),并将正确的区域设置缩写附加到数字上。 例如10米(10分钟),3d(3天),1年(1年)。


编辑:以下是一些例子:

时间间隔:90000整个字符串:1d字符串输出:1d
时间间隔:900整个字符串:15米字符串:15米
时间间隔:13500整个字符串:3h 45m字符串输出:4h

作为一般规则,应用正常的舍入规则(3.4轮向下,3.6轮向上)。

使用DateComponentFormatter ,自iOS 8起可用:

 func format(duration: TimeInterval) -> String { let formatter = DateComponentsFormatter() formatter.allowedUnits = [.day, .hour, .minute, .second] formatter.unitsStyle = .abbreviated formatter.maximumUnitCount = 1 return formatter.string(from: duration)! } for d in [12600.0, 90000.0, 900.0, 13500.0] { let str = format(duration: d) print("\(d): \(str)") } 

这打印:

 12600.0: 4h 90000.0: 1d 900.0: 15m 13500.0: 4h 

Swift 3扩展:

 extension TimeInterval { func format() -> String? { let formatter = DateComponentsFormatter() formatter.allowedUnits = [.day, .hour, .minute, .second, .nanosecond] formatter.unitsStyle = .abbreviated formatter.maximumUnitCount = 1 return formatter.string(from: self) } } 

万一有人想要它.. 斯威夫特4

 extension TimeInterval { func format(using units: NSCalendar.Unit) -> String? { let formatter = DateComponentsFormatter() formatter.allowedUnits = units formatter.unitsStyle = .abbreviated formatter.zeroFormattingBehavior = .pad return formatter.string(from: self) }} 

用法示例:

 let value:TimeInterval = 12600.0 print("\(value.format(using: [.hour, .minute, .second])!)") 

结果将是:

 3h 30m 0s 

看一下NSDateComponentsFormatter类。 它允许您使用2个日期或使用NSTimeInterval计算您想要的任何单位,并自动支持不同的语言和语言环境。 关于这个问题,SO中有几篇post。

您可以使用NSDate和NSCalendar。 你可以这样说:

 let timeInterval:Double = 12600 let calendar = NSCalendar.currentCalendar() let date = NSDate(timeInterval: -timeInterval, sinceDate: NSDate()) let components = calendar.components([.Year,.Day,.Hour, .Minute, .Second, .Nanosecond], fromDate: date, toDate: NSDate(), options: []) let hour = components.hour //3 let minute = components.minute //30 

Per duncan和rmaddy的建议使用NSDateComponentsFormatter

我为你创造了一个function! 我希望你喜欢它。 这非常容易实现,并且非常可定制。

 func totime(time: Double) -> (String) { var timex = time var fancytime: String = "a while" if time < 61 { fancytime = "\(timex)s" } else if time < 3601 { timex = timex/60 timex = round(timex) fancytime = "\(timex)m" } else if time < 86401 { timex = timex/3600 timex = round(timex) fancytime = "\(timex)h" } else if Double(time) < 3.15576E+07 { timex = timex/86400 timex = round(timex) fancytime = "\(timex)d" } else { fancytime = "more than one year" } fancytime = fancytime.stringByReplacingOccurrencesOfString(".0", withString: "") return fancytime } 

经过测试,它完美无瑕:

 print(totime(90000)) // prints "1d" print(totime(900)) // prints "15m" print(totime(13500)) // prints "4h" 

只需用totime(Double)调用totime(Double)