iOS开发-格式化时间显示刚刚几分钟前几小时前等
在开发中经常遇到从服务端获取的时间戳,需要转换显示刚刚、几分钟前、几小时前、几天前、年月日等格式。
主要用到了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。
学习记录,每天不停进步。