美文网首页
Swift 微信时间格式的String扩展

Swift 微信时间格式的String扩展

作者: 喵喵粉 | 来源:发表于2020-10-10 09:15 被阅读0次

    代码链接 http://www.52im.net/thread-2371-1-1.html

    StringDateextension

    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
    

    相关文章

      网友评论

          本文标题:Swift 微信时间格式的String扩展

          本文链接:https://www.haomeiwen.com/subject/rgjdpktx.html