专业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 ?? "一万年") ... } }
在
HMStatusCell
的statusVM: 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 ?? "未知时间" ... } }
- 运行: 效果如下