iOS 时间处理(仿朋友圈、微博发布时间)

joewa718 8年前
   <p style="text-align:center"><img src="https://simg.open-open.com/show/aba293caa51c855aab534f9cf5ab0e61.jpg"></p>    <p style="text-align:center">仿朋友圈、微博时间.png</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4dc157f9729a9d06f46c5bc891b2fd17.jpg"></p>    <p style="text-align:center">微博时间.png</p>    <h2>前言</h2>    <p>我们有时候做项目从网络回调的时间数据并不是我们想要的类型,而是,这种格式的 Sat Dec 03 19:56:38 +0800 2016 ,而我们需要转成我们需要的时间 例如: xx分钟前/xx小时前/xx天前</p>    <h2>OC</h2>    <h3>主要代码及思路</h3>    <ul>     <li>建立NSDate的分类,创建两个方法一个返回NSDate,一个返回我们需要的时间格式</li>    </ul>    <pre>  <code class="language-objectivec">/** 获取到的时间字符串转成NSDate */  + (NSDate * )timeStringToDate: (NSString *)timeString;  /** 把NSDate转成自己需要的时间格式 */  - (NSString *)dateToRequiredString;</code></pre>    <ul>     <li>方法的实现,因为会用到 NSDateFormatter 和 NSCalendar 这两个类,而这两个类初始化的时候会非常耗时间,并且我们可能在不同的模块都会用到处理过后的时间,所以创建成单例</li>    </ul>    <pre>  <code class="language-objectivec">/** calender单例 */  + (instancetype)sharedCalender;    /** formatter单例 */  + (instancetype)sharedFormatter;</code></pre>    <ul>     <li> <p>NSDate的方法:</p> <p>1.返回NSDate</p> </li>    </ul>    <pre>  <code class="language-objectivec">+ (NSDate *)timeStringToDate: (NSString *)timeString {      /** /// "Sat Dec 03 19:56:38 +0800 2016",根据回调的时间字符串制定不一样的日期格式 */      NSString * formatterString = @"EEE  MMM dd HH:mm:ss zzz yyyy";      /** DateFormatter, Calendar初始化比较消耗内存, 定义成单例 */      [HHDateFormatter sharedFormatter].dateFormat = formatterString;      /** 指定区域,真机一定要指定 */      [HHDateFormatter sharedFormatter].locale = [NSLocale localeWithLocaleIdentifier: @"en"];        return [[HHDateFormatter sharedFormatter] dateFromString: timeString];  }</code></pre>    <p>2.返回需要的时间格式,使用NSCalender的方法进行判断</p>    <pre>  <code class="language-objectivec">- (NSString *)dateToRequiredString {      if ([[HHCalender sharedCalender] isDateInToday:self]) {          //如果是今天          int seconds = [[NSDate date] timeIntervalSinceDate:self];          if (seconds < 60) {              return @"刚刚";          } else if (seconds < 60 * 60) {              return [NSString stringWithFormat:@"%d分钟前", seconds / 60];          } else {              return [NSString stringWithFormat:@"%d小时前", seconds / 3600];          }      } else if ([[HHCalender sharedCalender] isDateInYesterday:self]) {          //如果是昨天 10: 10          [HHDateFormatter sharedFormatter].dateFormat = @"昨天 HH:mm";          [HHDateFormatter sharedFormatter].locale =  [NSLocale localeWithLocaleIdentifier: @"en"];          return [[HHDateFormatter sharedFormatter] stringFromDate:self];      } else {          //首先要取到今年是哪一年 2016          //再取到当前的date是哪一年, 再做比较          NSInteger thisYear = [[HHCalender sharedCalender] component:NSCalendarUnitYear fromDate: [NSDate date]];          NSInteger dateYear = [[HHCalender sharedCalender] component:NSCalendarUnitYear fromDate: self];          //是今年          if (thisYear == dateYear) {              [HHDateFormatter sharedFormatter].dateFormat = @"MM-dd HH:mm";              [HHDateFormatter sharedFormatter].locale =  [NSLocale localeWithLocaleIdentifier: @"en"];              return [[HHDateFormatter sharedFormatter] stringFromDate:self];          }          //往年          else {              [HHDateFormatter sharedFormatter].dateFormat = @"yyyy-MM-dd HH:mm";              [HHDateFormatter sharedFormatter].locale =  [NSLocale localeWithLocaleIdentifier: @"en"];              return [[HHDateFormatter sharedFormatter] stringFromDate:self];          }      }  }</code></pre>    <h2>Swift</h2>    <ul>     <li>实现的思路与OC的一致,把 DateFormatter 和 Calendar 定义成全局常量,这样在哪里访问到的都是同一个常量,和方法写在同一个文件,总共一个文件搞定</li>    </ul>    <pre>  <code class="language-objectivec">//DateFormatter, Calendar初始化比较消耗内存,一般定义成常量  let dateFormat = DateFormatter()  let calendar = Calendar.current    extension Date {      /// 在Swift3.0中, 分类里面的类方法,需要使用 static      static func timeStringToDate(timeString: String) -> Date {            /// "Sat Dec 03 19:56:38 +0800 2016",根据回调的时间字符串制定不一样的日期格式          dateFormat.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"          /// 指定区域,真机一定要指定          dateFormat.locale = Locale(identifier: "en")          /// 把时间字符串,转日期          return dateFormat.date(from: timeString)!      }        func dateToShowTime() -> String {          if calendar.isDateInToday(self) {              /// 间隔秒数              let timeInterval = Int(Date().timeIntervalSince(self))              /// 如果小于60秒              if timeInterval < 60 {                  return "刚刚"              }              /// 小于1小时              if timeInterval < 60 * 60 {                  return "\(timeInterval / 60)分钟前"              }              /// 小于1天,大于1小时              return "\(timeInterval / 3600)小时前"          }            /// 如果是昨天          if calendar.isDateInYesterday(self) {              dateFormat.dateFormat = "昨天 HH:mm "          } else {              /// 如果不是昨天              let year = calendar.component(.year, from: self)              let thisYear = calendar.component(.year, from: Date())                /// 如果是今年              if year == thisYear {                  dateFormat.dateFormat = "MM-dd HH:mm"              } else {                  dateFormat.dateFormat = "yyyy-MM-dd HH:mm"              }          }          dateFormat.locale = Locale(identifier: "en")            /// 返回需要的时间字符串          return dateFormat.string(from: self)      }  }</code></pre>    <h2>使用</h2>    <pre>  <code class="language-objectivec">NSString *timeString = @"Mon Dec 05 11:56:38 +0800 2016";      NSDate *timeDate = [NSDate timeStringToDate:timeString];      NSLog(@"--%@",timeDate);      NSString *requiredString = [timeDate dateToRequiredString];      NSLog(@"--%@",requiredString);</code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8c84405bdba6c307970210137693560f.jpg"></p>    <p style="text-align:center">控制台打印结果.png</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/e42431045177</p>    <p> </p>