时间戳转时间,要求显示今天、明天、后天、昨天、前天、本周几、上周几等样式。其余显示具体某天日期。
日期问题涉及到国际化、夏令时、时区、地区等等情况。自己计算经常会漏掉某些情况,所以直接使用系统提供的日历对象来处理。
直接上代码:
// 时间戳转具体时间 time 是时间戳,毫秒
func timeToDateString(time: String) -> String {
let nowDate = Date()
let showDate = Date.init(timeIntervalSince1970: (ceil((time)/1000000000000)) > 1 ? time/1000 : time)
// 使用系统日历对象
var calendar = Calendar.current
calendar.firstWeekday = 2 // 设置周一为周第一天,符合CN周显示
let set = NSSet.init(array: [Calendar.Component.year,
Calendar.Component.month,
Calendar.Component.weekOfMonth,
Calendar.Component.weekOfYear,// 一年中的第几个周
Calendar.Component.weekday,
Calendar.Component.day,
Calendar.Component.hour,
Calendar.Component.minute,
Calendar.Component.second]) as! Set<Calendar.Component>
let nowDateComp = calendar.dateComponents(set, from: nowDate)
let showDateComp = calendar.dateComponents(set, from: showDate)
guard showDateComp.year == nowDateComp.year else {
return NSDate.dateString(forTimeInterval: (self)/1000, format: "yyyy年MM月dd日 HH:mm")
// 天差。与当前天比较,正为昨天、前天,负数为明、后天
let diffDay = twoTimeDiffDay(fromTime: showDate, endTime: nowDate)
if isSameDay(beginDate: showDateComp, endDate: nowDateComp) {
dateString = "今天"
} else if diffDay == 1 {
dateString = "昨天"
} else if diffDay == 2 {
dateString = "前天"
} else if diffDay == -1 {
dateString = "明天"
} else if diffDay == -2 {
dateString = "后天"
}else if nowDateComp.weekOfYear == showDateComp.weekOfYear { //本周 周要用weekOfYear判断
dateString = "本周\(weakToDateString(dayOfWeek: showDateComp.weekday ?? -1))"
} else if nowDateComp.weekOfYear == (showDateComp.weekOfYear ?? 0) + 1 { //上周
dateString = "上周\(weakToDateString(dayOfWeek: showDateComp.weekday ?? -1))"
// 都不满足 显示转换的具体时间
else {
dateString = NSDate.dateString(forTimeInterval: (time)/1000, format: "yyyy年MM月dd日 HH:mm")
return dateString
private func isSameDay(beginDate: DateComponents, endDate: DateComponents) -> Bool {
return beginDate.year == endDate.year && beginDate.month == endDate.month && beginDate.day == endDate.day
private func twoTimeDiffDay(fromTime: Date, endTime: Date, calendar: Calendar = .current) -> Int {
let formerTime = calendar.startOfDay(for: fromTime)
let endTime = calendar.startOfDay(for: endTime)
return calendar.dateComponents([.day], from: formerTime, to: endTime).day ?? 1000
周转为中国周,周一为第一天
private func weakToDateString(weekDay: Int) -> String {
var dayString = ""
switch weekDay {
case 1:
dayString = "日"
case 2:
dayString = "一"
case 3:
dayString = "二"
case 4:
dayString = "三"
case 5:
dayString = "四"
case 6:
dayString = "五"
case 7:
dayString = "六"
default:
dayString = "NA"
return dayString
刚开始转换这个也走了不少弯路,用各种计算,考虑了很多情况。算出当前周范围,上一周范围,叠加月等等情况,在对比计算,好麻烦。。还会出现各种各样的问题。用了系统对象方便多了,bug少了,转换着也简单。特此记录一下。