美文网首页架构师之路程序员IOS开发
用NSCalendar处理类似微博发帖时间并封装

用NSCalendar处理类似微博发帖时间并封装

作者: Oniityann | 来源:发表于2016-03-14 15:41 被阅读209次

    服务器返回数据

    服务器返回数据往往是一整串时间, 放在发帖时间label上面太长不好看, 我们需要手动处理一下使其变得美观易读.

    代码

    Date+Category封装

    需要处理服务器返回一大段时间, 我们需要比较现在时间和发帖时间
    首先利用日期格式化类NSDateFormatter去格式化服务器返回的一长串时间字符串.

        //日期格式化类
        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        //设置日期格式
        dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss";
        
        (...此处省略其他代码)
    

    如果直接将以上代码放在cell里面读取会使cell里setModel方法显得冗长, 不美观, 我选择将它们封装起来. 为了便于其他人维护, 不再新建一类, 直接用date+category增加方法.
    在date+category方法中自己写入方法:- (NSDateComponents *)zyn_deltaFromDateString:(NSString *)dateString withDateFormat:(NSString *)dateFormat;
    然后实现

    /**
     比较传入时间和现在时间的差值
     
     @param dateString 获取的时间字符串
     @param dateFormat 字符串时间格式
     
     @return 差值
     */
    - (NSDateComponents *)zyn_deltaFromDateString:(NSString *)dateString
                               withDateFormat:(NSString *)dateFormat {
        //日期格式化类
        NSDateFormatter *zyn_dateFormat = [[NSDateFormatter alloc] init];
    
        //设置日期格式, 这里提取参数, 可以根据需求传入
        zyn_dateFormat.dateFormat = dateFormat;
        
        //创建时间
        NSDate *create = [zyn_dateFormat dateFromString:dateString];
        
        //日历
        NSCalendar *zyn_calendar = [NSCalendar currentCalendar];
        
        //比较时间
        NSCalendarUnit zyn_unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
        return [zyn_calendar components:zyn_unit fromDate:create toDate:self options:0];
    }
    

    时间判断

    在求出时间差值以后, 需要自己对时间进行判断, 做条件的话, 封装BOOL方法比较适合, 需要做时间判断的个人认为只需要做今年以内的时间判断就好了, 之前的时间, 去年, 前年, 大前年, 这种完全没必要.

    同样是在date类目中

    今年?

    - (BOOL)isCurrentYear {
        
        //现在时间
        NSDate *current = [NSDate date];
        
        //日历
        NSCalendar *calender = [NSCalendar currentCalendar];
        
        NSInteger currentYear = [calender component:NSCalendarUnitYear fromDate:current];
        NSInteger selfYear = [calender component:NSCalendarUnitYear fromDate:self];
        
        return currentYear == selfYear;
    }
    

    今天?

    - (BOOL)isToday {
        
        NSDate *current = [NSDate date];
        
        NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
        fmt.dateFormat = @"yyyy-MM-dd";
        
        NSString *nowStr = [fmt stringFromDate:current];
        NSString *selfStr = [fmt stringFromDate:self];
        
        return [nowStr isEqualToString:selfStr];
    }
    

    昨天?

    - (BOOL)isYesterday {
        
        NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
        fmt.dateFormat = @"yyyy-MM-dd";
        
        NSDate *currentDate = [fmt dateFromString:[fmt stringFromDate:[NSDate date]]];
        NSDate *selfDate = [fmt dateFromString:[fmt stringFromDate:self]];
        
        NSCalendar *calendar = [NSCalendar currentCalendar];
        
        NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
        NSDateComponents *cmps = [calendar components:unit fromDate:selfDate toDate:currentDate options:0];
        
        return cmps.year == 0 && cmps.month == 0 && cmps.day == 1;
    }
    

    OK, 时间类目封装完毕, 需要在cell的label上显示时间了.
    同样判断时间需要很长的代码, 写在cell上过于冗长, 影响美观, 既然label.text是字符串, 那么我们就在string+category中完成这些判断即可.


    string+category封装

    直接上代码了, 逻辑就不细说了, 反正先从大时间开始判断就行了

    #import "NSString+ZYNExtension.h"
    
    @implementation NSString (ZYNExtension)
    
    - (NSString *)zyn_timeWithString:(NSString *)timeStr
               andOriginalDateFormat:(NSString *)dateFormat
                  andYesterdayFormat:(NSString *)yFormat
                       andYearFormat:(NSString *)yearFormat {
        
        // 日期格式化类
        NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
        // 设置日期格式(y:年,M:月,d:日,H:时,m:分,s:秒)
        fmt.dateFormat = dateFormat;
        // 帖子的创建时间
        NSDate *create = [fmt dateFromString:timeStr];
        
        if (create.isCurrentYear) {
            if (create.isToday) {
                
                //取出时间组成
                NSDateComponents *cmps = [[NSDate date] zyn_deltaFromDateString:timeStr withDateFormat:dateFormat];
                
                if (cmps.hour >= 1) {
                    
                    return [NSString stringWithFormat:@"%zd小时前", cmps.hour];
                    
                    //大于一分钟还是大于半分钟还是大于几秒钟, 这个根据自己喜好再加判断就行
                } else if (cmps.minute >= 1) { 
                    
                    return [NSString stringWithFormat:@"%zd分钟前", cmps.minute];
                    
                } else {
                    
                    return @"刚刚";
                }
                
            } else if (create.isYesterday) {
                //传入昨天需要的时间格式
                fmt.dateFormat = yFormat;
                return [fmt stringFromDate:create];
                
            } else {
                
                //传入今年其他时间需要的格式
                fmt.dateFormat = yearFormat;
                return [fmt stringFromDate:create];
            }
            
        } else {
            return timeStr;
        }
    }
    @end
    

    String类目封装完事, 接下来就是在cell上显示了, model和cell中代码会非常简单


    model和cell中的代码

    在pch文件中引入上面的头文件

    model中代码

    #import "ZYNHomeModel.h"
    
    static NSString *const dateFormat = @"yyyy-MM-dd HH:mm:ss";
    
    @implementation ZYNHomeModel
    
    //重写网络获取的时间字符串get方法
    - (NSString *)createTime {
        
        return [[NSString string] zyn_timeWithString:_createTime
                               andOriginalDateFormat:dateFormat
                                  andYesterdayFormat:@"昨天 HH:mm"
                                       andYearFormat:@"MM-dd HH:mm"];
    }
    
    @end
    

    cell中代码

    在setModel方法中:
    self.timeLabel.text = self.homeModel.createTime;
    即可, 不用出现任何逻辑判断


    效果

    昨天 前天

    相关文章

      网友评论

        本文标题:用NSCalendar处理类似微博发帖时间并封装

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