美文网首页
Swift时间统一格式化

Swift时间统一格式化

作者: EASXAI | 来源:发表于2023-01-11 13:21 被阅读0次

时间格式化使用减少同一个format重复创建的开销
尽量不要使用YYYY大写的格式化年,否侧年末获取的时间可能不对
yyyy使用的是日历年,我们应该使用日历年这种方式
YYYY使用的是当前周所在的年份(Week of Year)
比如:2020年12月27日是周日,而周日是一周的开始。所以如果26日运行这个例子,年份上显示是没有问题的。而从2020年12月27日 00:00:00开始显示会有问题!


image.png

使用如下:

LDate.string(from: Date(), format: "yyyy-MM-dd")

时间类型枚举

public enum LDateFormat: Int {
    // 始终显示精确日期和时间
    case precise
    // specific 始终显示具体分钟
    case specific
    // short突出处理短时间
    case short
}

时间format缓存池

/// 根据外部传入的format不同缓存不同的DateFormatter对象,传入已存在的format格式对象直接返回不会再次创建

private extension DateFormatter {
    static func cached(withFormat format: String) -> DateFormatter {
        var cachedFormatters = LDate.shared.cachedFormatters
        if let cachedFormatter = cachedFormatters[format] {
            return cachedFormatter
        }
        let formatter = DateFormatter()
        formatter.locale = NSLocale.system // fix:iOS15.4~15.6 12小时制日期格式显示问题
        formatter.calendar = Calendar(identifier: .gregorian)
        formatter.dateFormat = format
        cachedFormatters[format] = formatter
        return formatter
    }
}

LDate类

    /// 单例
    fileprivate static let shared = LDate.init()
    ///  缓存DateFormatter对象池
    fileprivate var cachedFormatters = [String: DateFormatter]()
    /// LDateFormat为specific生效
    fileprivate let defaultFormat = "yyyy-MM-dd HH:mm:ss"
    /// 内部处理时间格式
    fileprivate lazy var dateFormatter: DateFormatter = {
        let format = DateFormatter()
        format.dateFormat = LDate.shared.defaultFormat
        format.locale = NSLocale.system // fix:iOS15.4~15.6 12小时制日期格式显示问题
        format.calendar = Calendar(identifier: .gregorian)
        return format
    }()

String转Date

    /**
     String转Date
     @param from String
     @param format 例如:yyyy-MM-dd
     */
    public class func date(from: String, format: String) -> Date? {
        let dateFormatter = DateFormatter.cached(withFormat: format)
        return dateFormatter.date(from: from)
    }

Date转String

    /**
     Date转String
     @param from Date
     @param format 例如:yyyy-MM-dd
     */
    public class func string(from: Date, format: String) -> String {
        let dateFormatter = DateFormatter.cached(withFormat: format)
        return dateFormatter.string(from: from)
    }

时间戳转String

/**
     时间戳转String
     @param timeStamp Int 时间戳
     @param format 例如:yyyy-MM-dd
     */
    public class func string(_ timeStamp: Int, format: String) -> String {
        let dateFormatter = DateFormatter.cached(withFormat: format)
        let date = NSDate(timeIntervalSince1970: TimeInterval(timeStamp)) as Date
        return dateFormatter.string(from: date)
    }

当前时间戳转字符串 对应不同时间格式

/**
 时间转换方法
 @param timeStamp 时间戳
 @param format 时间处理类型  precise // 始终显示精确日期和时间 specific // 始终显示具体分钟 short // 突出处理短时间
 */
public class func timeToString(_ timeStamp: Int, _ format: LDateFormat) -> String {
    let timeStr = NSNumber(value: timeStamp).stringValue
    // 时间戳位数大于10视为毫秒级,转秒级除以1000
    var timeInterval = timeStamp
    if timeStr.count > 10 {
        timeInterval /= 1000
    }
    switch format {
    case .precise:
        return preciseTimeStamp(timeInterval)
    case .specific:
        return specificTimeStamp(timeInterval)
    case .short:
        return shortTimeStamp(timeInterval)
    }
}

始终显示精确日期和时间

private func preciseTimeStamp(_ timeStamp: Int) -> String {
    // 所有时间 默认 yyyy-MM-DD xx:xx:xx
    let date = NSDate(timeIntervalSince1970: TimeInterval(timeStamp)) as Date
    return LDate.shared.dateFormatter.string(from: date)
}

始终显示具体分钟

private func specificTimeStamp(_ timeStamp: Int) -> String {
    let timeInterval = TimeInterval(timeStamp)
    let date = NSDate(timeIntervalSince1970: timeInterval) as Date
    // 当天0:00-24:00 xx:xx
    if date.isToday() {
        return timeToString(timeInterval, "HH:mm")
    }
    // 昨天0:00-24:00 昨天xx:xx
    if date.isYesterday() {
        let timeStr = timeToString(timeInterval, "HH:mm")
        return String(format: "昨天 %@", timeStr)
    }
    // 超过昨天且当年 MM-DD xx:xx
    if date.isThisYear() {
        return timeToString(timeInterval, "MM-dd HH:mm")
    }
    // 超过昨天且跨年 yyyy-MM-DD xx:xx
    return timeToString(timeInterval, "yyyy-MM-dd HH:mm")
}

突出处理短时间

private func shortTimeStamp(_ timeStamp: Int) -> String {
    var timeInterval: Int = 0, temp: Int = 0
    // 从传入时间到当前时间的差值 秒级
    timeInterval =  Int(Date().timeIntervalSince1970) - timeStamp
    // 获取有多少分钟
    temp = timeInterval / 60
    if temp < 1 { // 1分钟内 刚刚
        return "刚刚"
    }
    if temp < 60 { // 1小时内 xx分钟前
        return String(format: "%ld分钟前", temp)
    }
    // 获取有多少小时
    temp /= 60
    if temp < 24 { // 24小时内 xx小时前 (不考虑00:00前后,只要在24小时内)
        return String(format: "%ld小时前", temp)
    }
    let timeStampInterval = TimeInterval(timeStamp)
    let date = NSDate(timeIntervalSince1970: timeStampInterval) as Date
    if date.isYesterday() { // 超过24小时且在昨天 昨天
        return "昨天"
    }
    if date.isThisYear() { // 超过昨天且当年 MM-DD
        return timeToString(timeStampInterval, "MM-dd")
    }
    // 超过昨天且跨年 yyyy-MM-DD
    return timeToString(timeStampInterval, "yyyy-MM-dd")
}

时间戳 -> 日期

private func timeToString(_ timeStamp: TimeInterval, _ format: String?) -> String {
    let date = NSDate(timeIntervalSince1970: timeStamp) as Date
    let time = LDate.string(from: date, format: format ?? LDate.shared.defaultFormat)
    return time
}

相关文章

网友评论

      本文标题:Swift时间统一格式化

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