Swift 微信时间格式的String扩展
2020-10-10 本文已影响0人
喵喵粉
代码链接 http://www.52im.net/thread-2371-1-1.html
给String
和Date
的extension
extension String {
func extGetWxTimeString() -> String {
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
guard let cDate = fmt.date(from: self) else {
return ""
}
let rst = cDate.extGetWxTimeString()
return rst
}
}
extension Date {
/**
* 仿照微信中的消息时间显示逻辑,将时间戳(单位:毫秒)转换为友好的显示格式.
*
* 1)7天之内的日期显示逻辑是:今天、昨天(-1d)、前天(-2d)、星期?(只显示总计7天之内的星期数,即<=-4d);
* 2)7天之外(即>7天)的逻辑:直接显示完整日期时间。
*
* @param dt 日期时间对象(本次被判断对象)
* @param includeTime YES表示输出的格式里一定会包含“时间:分钟”,否则不包含(参考微信,不包含时分的情况,用于首页“消息”中显示时)
*
* @return 输出格式形如:“刚刚”、“10:30”、“昨天 12:04”、“前天 20:51”、“星期二”、“2019/2/21 12:09”等形式
* @since 1.3
*/
func extGetWxTimeString(_ includeTime: Bool = true) -> String {
let kCalendar = Calendar.current
// 当前时间 比我们实际时间慢了8个小时
let currentDate = Date()
let curComponents = kCalendar.dateComponents([.year, .month, .day, .weekday], from: currentDate)
let currentYear = curComponents.year
let currentMonth = curComponents.month
let currentDay = curComponents.day
// 目标判断时间
let srcComponents = kCalendar.dateComponents([.year, .month, .day, .weekday], from: self)
let srcYear = srcComponents.year
let srcMonth = srcComponents.month
let srcDay = srcComponents.day
// 要额外显示的时间分钟
let timeExtraStr = (includeTime ? getTimeString(date: self, format: " HH:mm") : "")
// 当年
if (currentYear == srcYear) {
let currentTimestamp = currentDate.extTimeStamp
let srcTimestamp = self.extTimeStamp
// 相差时间(单位:秒)
let delta = currentTimestamp - srcTimestamp
// 当天(月份和日期一致才是)
if(currentMonth == srcMonth && currentDay == srcDay) {
// 时间相差60秒以内
if (delta < 60) {
return "刚刚"
}
// 否则当天其它时间段的,直接显示“时:分”的形式
return getTimeString(date: self, format: "HH:mm")
}
// 当年 && 当天之外的时间(即昨天及以前的时间)
else {
// 昨天(以“现在”的时候为基准-1天)
let nowDate = Date()
let yesterdayDate = Date(timeInterval: -24*60*60, since: nowDate)
let yesterdayComponents = kCalendar.dateComponents([.year, .month, .day, .weekday], from: yesterdayDate)
let yesterdayMonth = yesterdayComponents.month
let yesterdayDay = yesterdayComponents.day
// 前天(以“现在”的时候为基准-2天)
let beforeYesterdayDate = Date(timeInterval: -48*60*60, since: nowDate)
let beforeYesterdayComponents = kCalendar.dateComponents([.year, .month, .day, .weekday], from: beforeYesterdayDate)
let beforeYesterdayMonth = beforeYesterdayComponents.month
let beforeYesterdayDay = beforeYesterdayComponents.day
// 用目标日期的“月”和“天”跟上方计算出来的“昨天”进行比较,是最为准确的(如果用时间戳差值
// 的形式,是不准确的,比如:现在时刻是2019年02月22日1:00、而srcDate是2019年02月21日23:00,
// 这两者间只相差2小时,直接用“delta/3600” > 24小时来判断是否昨天,就完全是扯蛋的逻辑了)
if (srcMonth == yesterdayMonth && srcDay == yesterdayDay) {
return "昨天\(timeExtraStr)"// -1d
}
// “前天”判断逻辑同上
else if (srcMonth == beforeYesterdayMonth && srcDay == beforeYesterdayDay) {
return "前天\(timeExtraStr)"// -2d
}
else {
// 跟当前时间相差的小时数
let deltaHour = (delta/3600)
// 如果小于或等 7*24小时就显示星期几
if (deltaHour <= 7*24) {
let weekdays = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"]
// 取出的星期数:1表示星期天,2表示星期一,3表示星期二。。。。 6表示星期五,7表示星期六
guard let srcWeekday = srcComponents.weekday else {
return ""
}
// 取出当前是星期几
let weedayDesc = weekdays[srcWeekday-1]
return "\(weedayDesc)\(timeExtraStr)"
}
// 否则直接显示完整日期时间
else {
return "\(getTimeString(date: self, format: "yyyy/M/d"))\(timeExtraStr)"
}
}
}
}
// 往年
return "\(getTimeString(date: self, format: "yyyy/M/d"))\(timeExtraStr)"
}
fileprivate func getTimeString(date: Date, format: String) -> String {
let fmt = DateFormatter()
fmt.dateFormat = format
let rst = fmt.string(from: date)
return rst
}
}
/**
let millisecond = Date().milliStamp
print("当前毫秒级时间戳是 millisecond == ",millisecond)
let timeStamp = Date().timeStamp
print("当前秒级时间戳是 timeStamp == ",timeStamp)
输出结果
当前毫秒级时间戳是 millisecond == 1524801851988
当前秒级时间戳是 timeStamp == 1524801851
*/
extension Date {
/// 获取当前 秒级 时间戳 - 10位
var extTimeStamp : CLongLong {
let timeInterval: TimeInterval = timeIntervalSince1970
let timeStamp = CLongLong(timeInterval)
return timeStamp
}
/// 获取当前 毫秒级 时间戳 - 13位
var extMilliStamp : CLongLong {
let timeInterval: TimeInterval = timeIntervalSince1970
let millisecond = CLongLong(round(timeInterval*1000))
return millisecond
}
/// 获取当前 秒级 时间戳 - 10位
var extTimeStampStr : String {
let timeInterval: TimeInterval = timeIntervalSince1970
let timeStamp = Int(timeInterval)
return "\(timeStamp)"
}
/// 获取当前 毫秒级 时间戳 - 13位
var extMilliStampStr : String {
let timeInterval: TimeInterval = timeIntervalSince1970
let millisecond = CLongLong(round(timeInterval*1000))
return "\(millisecond)"
}
/// 获取当前date字符串
var extNowDateString: String {
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
return fmt.string(from: Date())
}
}
调用
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let fmt = DateFormatter()
fmt.dateFormat = "yyyy-MM-dd HH:mm:ss"
var nowDate = Date()
print("当前date:", nowDate)
let nowDateStr = fmt.string(from: nowDate)
print("当前date str:", nowDateStr)
nowDate = fmt.date(from: nowDateStr)!
print("当前date:", nowDate)
let times = ["2020-10-09 22:06:43",
"2020-10-08 08:23:44",
"2020-10-07 01:23:45",
"2030-10-01 01:23:45",
"2011-12-02 13:23:46"]
for time in times {
guard let cDate = fmt.date(from: time) else { return }
var rst = cDate.extGetWxTimeString()
print("\n1 字串:", time, "转成date:", cDate, " --->", rst)
rst = time.extGetWxTimeString()
print("2 字串:", time, "转成date:", cDate, " --->", rst)
}
}
打印
当前date: 2020-10-10 01:15:35 +0000
当前date str: 2020-10-10 09:15:35
当前date: 2020-10-10 01:15:35 +0000
1 字串: 2020-10-09 22:06:43 转成date: 2020-10-09 14:06:43 +0000 ---> 昨天 22:06
2 字串: 2020-10-09 22:06:43 转成date: 2020-10-09 14:06:43 +0000 ---> 昨天 22:06
1 字串: 2020-10-08 08:23:44 转成date: 2020-10-08 00:23:44 +0000 ---> 前天 08:23
2 字串: 2020-10-08 08:23:44 转成date: 2020-10-08 00:23:44 +0000 ---> 前天 08:23
1 字串: 2020-10-07 01:23:45 转成date: 2020-10-06 17:23:45 +0000 ---> 星期三 01:23
2 字串: 2020-10-07 01:23:45 转成date: 2020-10-06 17:23:45 +0000 ---> 星期三 01:23
1 字串: 2030-10-01 01:23:45 转成date: 2030-09-30 17:23:45 +0000 ---> 2030/10/1 01:23
2 字串: 2030-10-01 01:23:45 转成date: 2030-09-30 17:23:45 +0000 ---> 2030/10/1 01:23
1 字串: 2011-12-02 13:23:46 转成date: 2011-12-02 05:23:46 +0000 ---> 2011/12/2 13:23
2 字串: 2011-12-02 13:23:46 转成date: 2011-12-02 05:23:46 +0000 ---> 2011/12/2 13:23