iOS开发-格式化时间显示刚刚几分钟前几小时前等

iOS开发-格式化时间显示刚刚几分钟前几小时前等

在开发中经常遇到从服务端获取的时间戳,需要转换显示刚刚、几分钟前、几小时前、几天前、年月日等格式。

iOS开发-格式化时间显示刚刚几分钟前几小时前等_第1张图片

主要用到了NSCalendar、NSDateComponents这两个类

NSString *result = nil;
        NSCalendarUnit components = (NSCalendarUnit)(NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond);
        NSDateComponents *nowDateComponents = [[NSCalendar currentCalendar] components:components fromDate:timeNowDate];
        NSDateComponents *msgDateComponents = [[NSCalendar currentCalendar] components:components fromDate:anotherday];

一、NSCalendar与NSDateComponents

NSCalendar日历,支持日历的计算。
NSDateComponents 一个日期是有年月日时分秒组成的,components这个类的作用就是把日期拆分成单独的年、月、日、时、分、秒

假设有某个时间为customDate,类型为NSDate,如何知道改日期的具体年份、月、日呢。这个就要用到NSDateComponents:
NSDateComponents的方法

- (NSDateComponents *)components:(NSCalendarUnit)unitFlags 
fromDate:(NSDate *)date

unitFlags为枚举类型如下

typedef NS_OPTIONS(NSUInteger, NSCalendarUnit) {
        NSCalendarUnitEra                = kCFCalendarUnitEra,
        NSCalendarUnitYear               = kCFCalendarUnitYear,
        NSCalendarUnitMonth              = kCFCalendarUnitMonth,
        NSCalendarUnitDay                = kCFCalendarUnitDay,
        NSCalendarUnitHour               = kCFCalendarUnitHour,
        NSCalendarUnitMinute             = kCFCalendarUnitMinute,
        NSCalendarUnitSecond             = kCFCalendarUnitSecond,
        NSCalendarUnitWeekday            = kCFCalendarUnitWeekday,
        NSCalendarUnitWeekdayOrdinal     = kCFCalendarUnitWeekdayOrdinal,
        NSCalendarUnitQuarter            API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitQuarter,
        NSCalendarUnitWeekOfMonth        API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitWeekOfMonth,
        NSCalendarUnitWeekOfYear         API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitWeekOfYear,
        NSCalendarUnitYearForWeekOfYear  API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = kCFCalendarUnitYearForWeekOfYear,
        NSCalendarUnitNanosecond         API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = (1 << 15),
        NSCalendarUnitCalendar           API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)) = (1 << 20),
        NSCalendarUnitTimeZone           API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)) = (1 << 21),
};

常用的类型说明

NSCalendarUnitEra                 -- 纪元单位。  
NSCalendarUnitYear                -- 年单位。
NSCalendarUnitMonth               -- 月单位。范围为1-12
NSCalendarUnitDay                 -- 天单位。范围为1-31
NSCalendarUnitHour                -- 小时单位。范围为0-24
NSCalendarUnitMinute              -- 分钟单位。范围为0-60
NSCalendarUnitSecond              -- 秒单位。范围为0-60
NSCalendarUnitWeekOfMonth         -- 月包含的周数。
NSCalendarUnitWeekOfYear          -- 年包含的周数。
NSCalendarUnitWeekday             -- 工作日单位。范围为1-7

fromDate对应的日期

//根据系统区域设置获取用户的当前日历
NSCalendar *calendar = [NSCalendar currentCalendar];
//获取对应包含年月日的日期组件
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:customDate];
[components year];//年
[components month];//月
[components day];//日

二、实现获取时间戳与当前时间进行比对

从服务端获取的时间戳,需要转换显示刚刚、几分钟前、几小时前、几天前、年月日等格式。
例如显示刚刚

long dateTime = [anotherday timeIntervalSince1970];
long nowTimestamp = [timeNowDate timeIntervalSince1970];

if ((dateTime-zeroTime)>0) { //今日
    if ((nowTimestamp - dateTime) <= 60) {
        //如果是一分钟内的消息,显示刚刚
        return @"刚刚";
    }
    
    return timeArr[3];
}

完整代码如下

#import “SDTimeFormatUtil.h”

@implementation SDTimeFormatUtil

/**
 格式化时间
 
 @param timeStamp 时间秒数
 @return 字符串
 */
+ (NSString *)timeFormaterWithTimeStamp:(long)timeStamp {
    
    @try {
        NSDate *anotherday = [NSDate dateWithTimeIntervalSince1970:timeStamp];
        
        NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
        [formatter setDateFormat:@"yyyy-MM-dd-HH:mm"];
        
        NSDate *timeNowDate = [NSDate date];
        NSString *nowDate = [formatter stringFromDate:timeNowDate];
        NSArray *nowtimeArr = [nowDate componentsSeparatedByString:@"-"];
        NSString *nowYearStr = nowtimeArr[0];
        
        NSString *dateStr = [formatter stringFromDate:anotherday];
        NSArray *timeArr = [dateStr componentsSeparatedByString:@"-"];
        NSString *yearStr = timeArr[0];
        
        NSString *result = nil;
        NSCalendarUnit components = (NSCalendarUnit)(NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond);
        NSDateComponents *nowDateComponents = [[NSCalendar currentCalendar] components:components fromDate:timeNowDate];
        NSDateComponents *msgDateComponents = [[NSCalendar currentCalendar] components:components fromDate:anotherday];
        
        double OnedayTimeIntervalValue = 24*60*60;  //一天的秒数

        //为了判断当前时间是否为未来时间
        BOOL futureTime = ([anotherday timeIntervalSince1970]-[[NSDate date] timeIntervalSince1970]>0)?YES:NO;
        if (futureTime) {
            return [NSString stringWithFormat:@"%@/%@/%@",timeArr[0],timeArr[1],timeArr[2]];
        }
        
        int year = [yearStr intValue]-[nowYearStr intValue];
        if (year<0) {//过去(今年以前)
            return [NSString stringWithFormat:@"%@/%@/%@",timeArr[0],timeArr[1],timeArr[2]];
        }
        
        int zeroTime = [self zeroOfDate];
        long dateTime = [anotherday timeIntervalSince1970];
        long nowTimestamp = [timeNowDate timeIntervalSince1970];

        if ((dateTime-zeroTime)>0) { //今日
            if ((nowTimestamp - dateTime) <= 60) {
                //如果是一分钟内的消息,显示刚刚
                return @"刚刚";
            }
            
            return timeArr[3];
        }
        
        if ((zeroTime-dateTime)<24*3600) {//昨日
            return @"昨天";
        }
        
        if([timeNowDate timeIntervalSinceDate:anotherday] < 7 * OnedayTimeIntervalValue) {
            //一周内
            NSString *weekDay = [SDTimeFormatUtil weekdayStr:msgDateComponents.weekday];
            return weekDay;
        }
        
        return [NSString stringWithFormat:@"%@/%@",timeArr[1],timeArr[2]];
    } @catch (NSException *exception) {
        //出现异常
        return [NSString stringWithFormat:@"%ld",timeStamp];
    }
}

+ (NSString*)weekdayStr:(NSInteger)dayOfWeek {
    static NSDictionary *daysOfWeekDict = nil;
    daysOfWeekDict = @{@(1):@"星期日",
                       @(2):@"星期一",
                       @(3):@"星期二",
                       @(4):@"星期三",
                       @(5):@"星期四",
                       @(6):@"星期五",
                       @(7):@"星期六",};
    return [daysOfWeekDict objectForKey:@(dayOfWeek)];
}

/**
 今日时间范围内的具体划分

 @param date date
 @return 今日时间格式
 */
+ (NSString *)timeStringOfToday:(NSDate *)date {
    NSDate *today = [NSDate date];
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    unsigned int unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    
    NSDateComponents *components = [gregorian components:unitFlags fromDate:date toDate:today options:0];
    
    /*
    if ([components hour]) {
        return [NSString stringWithFormat:@"%ld小时前",(long)[components hour]];
    }
    if ([components minute]) {
        return [NSString stringWithFormat:@"%ld分钟前",(long)[components minute]];
    }
     */
    if ([components hour]) {
        //几个小时前
        return [NSString stringWithFormat:@"%02ld:%02ld",components.hour,components.minute];
    }
    if ([components minute]) {
        //多少分钟前
        return [NSString stringWithFormat:@"%02ld:%02ld",components.hour,components.minute];
    }
    
    if ([components second]) {
        return @"刚刚";
    }
    
    return @"刚刚";
}

/**
 今日零点

 @return 整型
 */
+ (int)zeroOfDate {
    
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:[NSDate date]];
    components.hour = 0;
    components.minute = 0;
    components.second = 0;
    NSTimeInterval ts = (int)[[calendar dateFromComponents:components] timeIntervalSince1970];
    
    return ts;
}

/**
 返回格式为YYYY-dd-mm的时间字符串
 
 @return 时间字符串
 */
+ (NSString *)formatterDayDate:(long)timeStamp {
    NSDate *date = [SDTimeFormatUtil getDateTimeFromTimeStamp:timeStamp];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"YYYY-MM-dd"];
    
    NSString *dateStr = nil;
    if (self) {
        dateStr = [dateFormatter stringFromDate:date];
    }
    
    return dateStr;
}

/**
 将时间戳转换为NSDate类型

 @param timeStamp timeStamp
 @return date
 */
+ (NSDate *)getDateTimeFromTimeStamp:(long)timeStamp {
    return [NSDate dateWithTimeIntervalSince1970:timeStamp];
}

@end

三、小结

iOS开发-格式化时间显示刚刚几分钟前几小时前等

从服务端获取的时间戳,需要转换显示刚刚、几分钟前、几小时前、几天前、年月日等格式。 NSCalendar与NSDateComponents。

学习记录,每天不停进步。

你可能感兴趣的:(移动开发,iphone开发,Objective-c,ios,cocoa,macos,NSCalendar,日历,格式化时间)