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

服务器返回数据

服务器返回数据往往是一整串时间, 放在发帖时间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处理类似微博发帖时间并封装)