专业java、php、iOS、C++、网页设计、平面设计、网络营销、游戏开发、前端与移动开发培训机构

新浪日期处理

日期格式

    • y 将年份 (0-9) 显示为不带前导零的数字
    • yy 以带前导零的两位数字格式显示年份
    • yyy 以四位数字格式显示年份
    • yyyy 以四位数字格式显示年份
    • M 将月份显示为不带前导零的数字(如一月表示为 1)
    • MM 将月份显示为带前导零的数字
    • MMM 将月份显示为缩写形式(例如 Jan)
    • MMMM 将月份显示为完整月份名(例如 January)
      • 一月 Jan January
      • 二月 Feb February
      • 三月 Mar March
      • 四月 Apr April
      • 五月 May May
      • 六月 Jun June
      • 七月 Jul July
      • 八月 Aug August
      • 九月 Sep September
      • 十月 Oct October
      • 十一月 Nov November
      • 十二月 Dec December
    • d 将日显示为不带前导零的数字(如 1)
    • dd 将日显示为带前导零的数字(如 01)
  • 星期
    • EEE 将日显示为缩写形式(例如 Sun)
    • EEEE 将日显示为全名(例如 Sunday)
      • 星期一 Mon Monday
      • 星期二 Tue Tuesday
      • 星期三 Wed Wednesday
      • 星期四 Thu Thursday
      • 星期五 Fri Friday
      • 星期六 Sat Saturday
      • 星期天 Sun Sunday
  • 小时
    • h 使用 12 小时制将小时显示为不带前导零的数字(例如 1:15:15 PM)
    • hh 使用 12 小时制将小时显示为带前导零的数字(例如 01:15:15 PM)
    • H 使用 24 小时制将小时显示为不带前导零的数字(例如 1:15:15)
    • HH 使用 24 小时制将小时显示为带前导零的数字(例如 01:15:15)
  • 分钟
    • m 将分钟显示为不带前导零的数字(例如 12:1:15)
    • mm 将分钟显示为带前导零的数字(例如 12:01:15)
    • s 将秒显示为不带前导零的数字(例如 12:15:5)
    • ss 将秒显示为带前导零的数字(例如 12:15:05)
    • f 显示秒的小数部分
    • ff 将精确显示到百分之一秒
    • ffff 将精确显示到万分之一秒
    • 用户定义格式中最多可使用七个 f 符号
  • 上午&下午
    • t 使用 12 小时制
      • 中午之前任一小时显示大写的 A
      • 中午到 11:59 PM 之间的任一小时显示大写的 P
    • tt 对于使用 12 小时制的区域设置
      • 中午之前任一小时显示大写的 AM
      • 中午到 11:59 PM 之间的任一小时显示大写的 PM
    • 对于使用 24 小时制的区域设置,不显示任何字符
  • 时区
    • z 显示不带前导零的时区偏移量
    • zz 显示带前导零的时区偏移量(例如 -08)
    • zzz 显示完整的时区偏移量(例如 -0800)
  • 纪元
    • gg 显示时代/纪元字符串(例如 A.D.)

新浪微博日期格式

Sun May 24 12:12:00 +0800 2015
星期 月 日 时:分:秒 时区 年

要从一个字符串中解析得到准确的时间,必须要指定正确的格式字符串

将新浪返回的时间转换成系统的NSDate

override func viewDidLoad() {
    super.viewDidLoad()

    /// 微博返回时间
    let created_at = "Mon Nov 02 09:33:44 +0800 2015"

    /// 日期格式化类
    let df = DateFormatter()

    /// 指定区域,真机一定要指定
    df.locale = Locale(identifier: "en")

    /// 设置日期格式
    df.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"

    /// 将字符串转成NSDate
    let date = df.date(from: created_at)
    print("date:\(date)")
}
  • 抽取到NSDate的扩展,建立 NSDate+Extension.swift

    extension Date {
      /**
       将新浪日期转成系统日期:    如:2015-05-24 04:12:00 +0000
       - parameter string: 新浪日期
       - returns: 系统日期
       */
      static func dateDescription(fromSinaDateString string: String) -> Void {
    
          /// 日期格式化类
          let df = DateFormatter()
    
          /// 指定区域,真机一定要指定
          df.locale = Locale(identifier: "en")
    
          /// 设置日期格式
          df.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"
    
          /// 将字符串转成NSDate
          let date = df.date(from: string) ?? Date()
      }
    }
    

日期需求

  • 刚刚(一分钟内)
  • X分钟前(一小时内)
  • X小时前(当天)
  • 昨天 HH:mm(昨天)
  • MM-dd HH:mm(一年内)
  • yyyy-MM-dd HH:mm(更早期)

  • NSDate+Extension.swift 定义如下函数

    ///  返回日期描述字符串
    ///
    ///     格式如下
    ///     -   刚刚(一分钟内)
    ///     -   X分钟前(一小时内)
    ///     -   X小时前(当天)
    ///     -   昨天 HH:mm(昨天)
    ///     -   MM-dd HH:mm(一年内)
    ///     -   yyyy-MM-dd HH:mm(更早期)
    func compareDate() -> String {
      return ""
    }
    

在 iOS 中处理日期的详细信息需要借助到 NSCalendar 类,NSCalendar 提供了非常丰富的日期操作函数

  • 日期分段判断

    /// 日期描述字符串
    func compareDate() -> String {
    
      // 1. 获取当前日历
      let calendar = NSCalendar.current
    
      // 2. 判断当前日期
      if calendar.isDateInToday(self) {
          return "今天"
      }
    
      // 3. 其他日期
      if calendar.isDateInYesterday(self) {
          return "昨天"
      }
    
      return "其他"
    }
    
  • dateDescription 调用 compareDate

    static func dateDescription(fromSinaDateString string: String) -> Void {
    
      /// 日期格式化类
      let df = DateFormatter()
    
      /// 指定区域,真机一定要指定
      df.locale = Locale(identifier: "en")
    
      /// 设置日期格式
      df.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"
    
      /// 将字符串转成NSDate
      let date = df.date(from: string) ?? Date()
    
      let description = date.compareDate()
      print("description = \(description)")
    }
    
  • 测试数据
    let created_at = "Mon Sep 12 12:14:25 +0800 2016"
    Date.dateDescription(fromSinaDateString: created_at)
    
  • 计算今天的日期信息

    /// 日期描述字符串
    func compareDate() -> String {
    
      // 1. 获取当前日历
      let calendar = NSCalendar.current
    
      // 2. 判断当前日期
      if calendar.isDateInToday(self) {
          // 获取self和当前日期相差的秒数
          let delta = Int(Date().timeIntervalSince(self))
          if delta < 60 {
              return "刚刚"
          }
    
          if delta < 60 * 60 {
              return "\(delta / 60) 分钟前"
          }
          return "\(delta / 3600) 小时前"
      }
    
      // 3. 其他日期
      if calendar.isDateInYesterday(self) {
          return "昨天"
      }
    
      return "其他"
    }
    
  • compareDate 比较是否同一年
    let result = calendar.compare(self, to: Date(), toGranularity: Calendar.Component.year)
    if result == ComparisonResult.orderedSame {
      // 同一年
      return "同一年"
    } else {
      // 更早期
      return "更早期"
    }
    
  • compareDate 计算非今天的日期信息
    // 日期格式
    var format = ""
    //
    // 3. 其他日期
    if calendar.isDateInYesterday(self) {
      format = "昨天 HH:mm"
    } else if calendar.compare(self, to: Date(), toGranularity: Calendar.Component.year) == ComparisonResult.orderedSame {
      // 同一年
      format = "MM-dd HH:mm"
    } else {
      // 更早期
      format = "yyyy-MM-dd HH:mm"
    }
    //
    // 根据指定的时间格式转成 时间字符串
    let df = DateFormatter()
    df.locale = Locale(identifier: "en")
    // 指定格式
    df.dateFormat = format
    // 将系统时间转成指定格式的字符串
    return df.string(from: self)
    
  • dateDescription 方法中返回 compareDate 的结果

    static func dateDescription(fromSinaDateString string: String) -> String {
    
      /// 日期格式化类
      let df = DateFormatter()
    
      /// 指定区域,真机一定要指定
      df.locale = Locale(identifier: "en")
    
      /// 设置日期格式
      df.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"
    
      /// 将字符串转成NSDate
      let date = df.date(from: string) ?? Date()
    
      return date.compareDate()
    }
    

    集成日期处理

  • 将分类拖拽至项目的 Extension(扩展) 目录

  • HMStatusViewModel 增加微博日期描述属性 sinaDateDescription, 在 init(status: HMStatus) 时给属性赋值

    /// 一个HMStatusViewModel包含一个微博模型
    class HMStatusViewModel: NSObject {
      // MARK: - 属性
      ...
      /// 微博日期描述
      var sinaDateDescription: String?
    
      // MARK: - 构造函数
      init(status: HMStatus) {
          self.status = status
    
          // 设置是否有被转发微博
          isRetweetStatus = status.retweeted_status != nil
    
          // 微博日期描述
          sinaDateDescription = Date.dateDescription(fromSinaDateString: status.created_at ?? "一万年")
    
          ...
      }
    }
    
  • HMStatusCellstatusVM: HMStatusViewModel 属性监视器中给 时间Label 赋值

    /// 微博ViewModel
    var statusVM: HMStatusViewModel? {
      didSet {
          guard let status = statusVM?.status else {
              print("statusVM中没有微博")
              return
          }
    
          // 头像,使用SDWebImage设置网络图片内容
          ...
          // 用户名称
          ...
    
          // 来源
    //            sourceLabel.text = status.source ?? "未知来源"
          sourceLabel.text = "来自 ***"
    
          // 时间
    //            timeLabel.text = status.created_at ?? "未知时间"
          timeLabel.text = statusVM?.sinaDateDescription ?? "未知时间"
    
          ...
      }
    }
    
  • 运行: 效果如下

results matching ""

    No results matching ""