Ios 如何在swift中设置用户显示(类似社交网络)的时间间隔?

Ios 如何在swift中设置用户显示(类似社交网络)的时间间隔?,ios,swift,nsdate,Ios,Swift,Nsdate,我有一个时间间隔,比如说12600,相当于3小时30分钟。如何设置任何此类时间间隔的格式,以便只保留时间间隔的最高部分(例如,在本例中为小时),并将正确的区域设置缩写添加到数字中。例如10米(10分钟)、3天(3天)、1年(1年) 编辑:以下是一些示例: Time interval in: 90000 Whole string: 1d String out: 1d Time interval in: 900 Whole string: 15m String o

我有一个时间间隔,比如说12600,相当于3小时30分钟。如何设置任何此类时间间隔的格式,以便只保留时间间隔的最高部分(例如,在本例中为小时),并将正确的区域设置缩写添加到数字中。例如10米(10分钟)、3天(3天)、1年(1年)


编辑:以下是一些示例:

Time interval in: 90000 Whole string: 1d String out: 1d Time interval in: 900 Whole string: 15m String out: 15m Time interval in: 13500 Whole String: 3h 45m String out: 4h 时间间隔输入:90000整串:1d串输出:1d 输入时间间隔:900整串:15m输出时间间隔:15m 输入时间间隔:13500整串:3h 45m输出时间:4h
作为一般规则,应用正常的舍入规则(向下舍入3.4,向上舍入3.6)。

您可以使用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

根据duncan和rmaddy的建议,使用NSDateComponents格式

查看
NSDateComponents格式
类。它允许您使用2个日期或NSTimeInterval计算所需的任何单位,并自动支持不同的语言和地区。关于这个问题,这里有几个帖子

我为您创建了一个函数!我希望你喜欢。这是非常容易实现和非常定制

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
}

只需使用
totime(Double)

调用它,如果您的目标是较新的操作系统版本(iOS 13.5+、OS X 10.15+),您可以使用:

let formatter=relativeDataTimeFormatter()
formatter.dateTimeStyle=.named
对于d英寸[-12600.0,-90000.0,-900.0,13500.0]{
设str=formatter.localizedString(fromTimeInterval:d)
打印(“\(d):\(str)”)
}
//输出
-12600.0:3小时前
-90000.0:昨天
-900.0:15分钟前
13500.0:3小时后

对于较旧的操作系统版本,请使用从iOS 8开始提供的:

func格式(持续时间:时间间隔)->字符串{
让格式化程序=DateComponentsFormatter()
formatter.allowedUnits=[.天、.小时、.分钟、.秒]
formatter.unitsStyle=.缩写
formatter.maximumUnitCount=1
返回格式化程序.string(from:duration)!
}
对于d英寸[12600.0,90000.0,900.0,13500.0]{
let str=格式(持续时间:d)
打印(“\(d):\(str)”)
}
这张照片是:

12600.0:4h
90000.0:1d
900.0:15米
13500.0:4小时

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)
  }
}

以防万一有人想要它Swift 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

请用具体的例子详细说明输入和输出的内容。如果时间是12600,你想把它变成3h?是的,这是正确的。我会再加上一些例子。请详细说明你想让它向上还是向下,3小时40分钟变成3小时还是4小时?我怎么知道哪一个是最好的礼物?如何显示正确的缩写?@beyowulf请参见
nsdatecomponentsformter
。好的,我的错。看看邓肯的回答!正是我所需要的答案很好。(投票,因为它比我的更完整。)我做了一些修补。奇怪的是,在格式化程序上设置
allowsFractilunits
标志不会像您预期的那样在13500秒内给出“3.75小时”。您必须将
maximumUnitCount
设置为2,然后您将获得
3小时45分钟
(这不是OP想要的)。我想知道为什么?知道吗,@code不同?为什么
.string(from:)
返回
可选的
?在什么情况下,它可以返回
nil
?这看起来很棒!但是,有没有办法获得持续时间间隔?e、 g.“1-2小时”?警告!这在59:30-59:59(秒3570-3599)时表现得有点奇怪-对于其中任何一个值,它都返回
0d
。所以倒数计时,你会得到像
2h
1h
0d
59m
58m
。。。我是唯一一个发现这种奇怪的人吗?你的回答并不像OP所问的那样处理不同的地区。CodeDifferent的答案是最好的。
3h 30m 0s