我正在尝试使用Swift将UTC格式的日期从API转换为人类可读的近似格式。
我正在寻找以下内容:
2015-07-14T13:51:05.423Z
到
大约两周前
Swift中最好的方法是什么?虽然最好这可以直接格式化字符串,但我知道这可能需要将字符串转换为NSDate对象。
非常感谢任何帮助。
编辑:我的问题已被确定为another question的可能副本。下面的Tom解决方案是为Swift编写的,并且比根据我的情况创建一个新方法更优雅。
答案 0 :(得分:31)
您需要两个步骤。首先,将日期字符串转换为NSDate
:
let dateString = "2015-07-14T13:51:05.423Z"
let df = NSDateFormatter()
df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = df.dateFromString(dateString)
(如果这不是您获得的字符串的精确表示,则您必须更改日期格式字符串以使其转换)。
接下来,使用NSDateComponentsFormatter
获取所需的字符串:
let formatter = NSDateComponentsFormatter()
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyle.Full
formatter.includesApproximationPhrase = true
formatter.includesTimeRemainingPhrase = false
formatter.allowedUnits = NSCalendarUnit.WeekOfMonthCalendarUnit
if let pastDate = date {
let dateRelativeString = formatter.stringFromDate(pastDate, toDate: NSDate())
}
今天是7月28日,所以该字符串的结果是"大约2周"。 allowedUnits
属性是一个位字段,因此您可以指定任意数量的单位类型。
答案 1 :(得分:3)
正如Tom Harrington的回答说明,您可以使用NSDateComponentsFormatter
生成时刻或时间间隔的口语表示。
但是,如果你想要完全解决问题在其示例中提出的问题,那就是产生一个过去时刻的口语表示,相对于当前时刻,就像时间轴一样面向用户界面,似乎NSDateComponentsFormatter
似乎不合适。正如stringFromTimeInterval(_:)
的文档所述,时间间隔值"必须是有限数。创建字符串时,负数被视为正数。"
尽我所知,最好的选择是TTTTimeIntervalFormatter
,这是Mattt Thompson FormatterKit中的一个独立课程。
我制作了一个Xcode 7游乐场RelativeDatePlayground,用于比较NSDateFormatter
输出到TTTTimeIntervalFormatter
的输出。这是一个表格,显示不同相对时间的输出,以秒为单位。正如您所看到的,NSDateComponentsFormatter
似乎无法处理过去的时刻或当前时刻:
-1488010 | 2 weeks ago | -1 week remaining
-1468800 | 2 weeks ago | -1 week remaining
-864000 | 1 week ago | 0 seconds remaining
-86400 | 1 day ago | -1 day remaining
-36000 | 10 hours ago | -10 hours remaining
-3600 | 1 hour ago | -1 hour remaining
-600 | 10 minutes ago | -10 minutes remaining
-60 | 1 minute ago | -1 minute remaining
-10 | 10 seconds ago | -10 seconds remaining
-1 | 1 second ago | -1 second remaining
-0 | just now | 0 seconds remaining
0 | just now | 0 seconds remaining
1 | 1 second from now | 1 second remaining
10 | 10 seconds from now | 10 seconds remaining
60 | 1 minute from now | 1 minute remaining
600 | 10 minutes from now | 10 minutes remaining
3600 | 1 hour from now | 1 hour remaining
36000 | 10 hours from now | 10 hours remaining
86400 | 1 day from now | 1 day remaining
864000 | 1 week from now | 1 week remaining
1468800 | 2 weeks from now | 2 weeks remaining
1488010 | 2 weeks from now | 2 weeks remaining
答案 2 :(得分:0)
从 iOS 13 / macOS 10.15 开始,您可以使用 RelativeDateTimeFormatter
。
感谢 @mattt 将其放在您的 archived Github README 上。
import Foundation
let formatter = RelativeDateTimeFormatter()
formatter.formattingContext = .beginningOfSentence
let date = Date().addingTimeInterval(-67 * 60)
formatter.string(for: date)! // => "1 hour ago"