iOS NSDate 常用日期相关函数的封装
Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。
NSDate+Category.h 代码:
#import <Foundation/Foundation.h> #define D_MINUTE 60 #define D_HOUR 3600 #define D_DAY 86400 #define D_WEEK 604800 #define D_YEAR 31556926 @interface NSDate (Category) - (NSString *)timeIntervalDescription; //距离当前的时间间隔描述 - (NSString *)minuteDescription; //精确到分钟的日期描述*/ - (NSString *)formattedTime; - (NSString *)formattedDateDescription; //格式化日期描述 - (double)timeIntervalSince1970InMilliSecond; + (NSDate *)dateWithTimeIntervalInMilliSecondSince1970:(double)timeIntervalInMilliSecond; + (NSString *)formattedTimeFromTimeInterval:(long long)time; //从当前日期起的相对日期 + (NSDate *) dateTomorrow; + (NSDate *) dateYesterday; + (NSDate *) dateWithDaysFromNow: (NSInteger) days; + (NSDate *) dateWithDaysBeforeNow: (NSInteger) days; + (NSDate *) dateWithHoursFromNow: (NSInteger) dHours; + (NSDate *) dateWithHoursBeforeNow: (NSInteger) dHours; + (NSDate *) dateWithMinutesFromNow: (NSInteger) dMinutes; + (NSDate *) dateWithMinutesBeforeNow: (NSInteger) dMinutes; + (NSString *)weekdayStringValue:(NSDate*)date; //日期比较 - (BOOL) isEqualToDateIgnoringTime: (NSDate *) aDate; - (BOOL) isToday; - (BOOL) isTomorrow; - (BOOL) isYesterday; - (BOOL) isSameWeekAsDate: (NSDate *) aDate; - (BOOL) isThisWeek; - (BOOL) isNextWeek; - (BOOL) isLastWeek; - (BOOL) isSameMonthAsDate: (NSDate *) aDate; - (BOOL) isThisMonth; - (BOOL) isSameYearAsDate: (NSDate *) aDate; - (BOOL) isThisYear; - (BOOL) isNextYear; - (BOOL) isLastYear; - (BOOL) isEarlierThanDate: (NSDate *) aDate; - (BOOL) isLaterThanDate: (NSDate *) aDate; - (BOOL) isInFuture; - (BOOL) isInPast; //工作日和休息日 - (BOOL) isTypicallyWorkday; - (BOOL) isTypicallyWeekend; //日期调整 - (NSDate *) dateByAddingDays: (NSInteger) dDays; - (NSDate *) dateBySubtractingDays: (NSInteger) dDays; - (NSDate *) dateByAddingHours: (NSInteger) dHours; - (NSDate *) dateBySubtractingHours: (NSInteger) dHours; - (NSDate *) dateByAddingMinutes: (NSInteger) dMinutes; - (NSDate *) dateBySubtractingMinutes: (NSInteger) dMinutes; - (NSDate *) dateAtStartOfDay; //检索的时间间隔 - (NSInteger) minutesAfterDate: (NSDate *) aDate; - (NSInteger) minutesBeforeDate: (NSDate *) aDate; - (NSInteger) hoursAfterDate: (NSDate *) aDate; - (NSInteger) hoursBeforeDate: (NSDate *) aDate; - (NSInteger) daysAfterDate: (NSDate *) aDate; - (NSInteger) daysBeforeDate: (NSDate *) aDate; - (NSInteger)distanceInDaysToDate:(NSDate *)anotherDate; //分解的日期 @property (readonly) NSInteger nearestHour; @property (readonly) NSInteger hour; @property (readonly) NSInteger minute; @property (readonly) NSInteger seconds; @property (readonly) NSInteger day; @property (readonly) NSInteger month; @property (readonly) NSInteger week; @property (readonly) NSInteger weekday; @property (readonly) NSInteger nthWeekday; // e.g. 2nd Tuesday of the month == 2 @property (readonly) NSInteger year; #pragma mark 日期格式化 + (id)dateFormatter; + (id)dateFormatterWithFormat:(NSString *)dateFormat; + (id)defaultDateFormatter;/*yyyy-MM-dd HH:mm:ss*/ @end
NSDate+Category.m 代码:
#import "NSDate+Category.h" #define DATE_COMPONENTS (NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekOfYear | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal) #define CURRENT_CALENDAR [NSCalendar currentCalendar] @implementation NSDate (Category) /** * @brief 距离当前的时间间隔描述 * * @param paramete 请求参数 * * @return NSString格式的请求参数 */ - (NSString *)timeIntervalDescription { NSTimeInterval timeInterval = -[self timeIntervalSinceNow]; if (timeInterval < 60) { return @"1分钟内"; } else if (timeInterval < 3600) { return [NSString stringWithFormat:@"%ld分钟前", (long)timeInterval/60]; } else if (timeInterval < 86400) { return [NSString stringWithFormat:@"%ld小时前", (long)timeInterval / 3600]; } else if (timeInterval < 2592000) {//30天内 return [NSString stringWithFormat:@"%ld天前", (long)timeInterval / 86400]; } else if (timeInterval < 31536000) {//30天至1年内 NSDateFormatter *dateFormatter = [NSDate dateFormatterWithFormat:@"M月d日"]; return [dateFormatter stringFromDate:self]; } else { return [NSString stringWithFormat:@"%ld年前", (long)timeInterval / 31536000]; } } /** * @brief 精确到分钟的日期描述 * * @param paramete 请求参数 * * @return NSString格式的请求参数 */ - (NSString *)minuteDescription { NSDateFormatter *dateFormatter = [NSDate dateFormatterWithFormat:@"yyyy-MM-dd"]; NSString *theDay = [dateFormatter stringFromDate:self];//日期的年月日 NSString *currentDay = [dateFormatter stringFromDate:[NSDate date]];//当前年月日 if ([theDay isEqualToString:currentDay]) {//当天 [dateFormatter setDateFormat:@"ah:mm"]; return [dateFormatter stringFromDate:self]; } else if ([[dateFormatter dateFromString:currentDay] timeIntervalSinceDate:[dateFormatter dateFromString:theDay]] == 86400) {//昨天 [dateFormatter setDateFormat:@"ah:mm"]; return [NSString stringWithFormat:@"昨天 %@", [dateFormatter stringFromDate:self]]; } else if ([[dateFormatter dateFromString:currentDay] timeIntervalSinceDate:[dateFormatter dateFromString:theDay]] < 86400 * 7) {//间隔一周内 [dateFormatter setDateFormat:@"EEEE ah:mm"]; return [dateFormatter stringFromDate:self]; } else {//以前 [dateFormatter setDateFormat:@"yyyy-MM-dd ah:mm"]; return [dateFormatter stringFromDate:self]; } } /** * @brief 标准时间日期描述 * * @param paramete 请求参数 * * @return NSString格式的请求参数 */ -(NSString *)formattedTime{ NSDateFormatter* formatter = [[NSDateFormatter alloc]init]; [formatter setDateFormat:@"YYYY-MM-dd"]; NSString * dateNow = [formatter stringFromDate:[NSDate date]]; NSDateComponents *components = [[NSDateComponents alloc] init]; [components setDay:[[dateNow substringWithRange:NSMakeRange(8,2)] intValue]]; [components setMonth:[[dateNow substringWithRange:NSMakeRange(5,2)] intValue]]; [components setYear:[[dateNow substringWithRange:NSMakeRange(0,4)] intValue]]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSDate *date = [gregorian dateFromComponents:components]; //今天 0点时间 NSInteger hour = [self hoursAfterDate:date]; NSDateFormatter *dateFormatter = nil; NSString *ret = @""; //hasAMPM==TURE为12小时制,否则为24小时制 NSString *formatStringForHours = [NSDateFormatter dateFormatFromTemplate:@"j" options:0 locale:[NSLocale currentLocale]]; NSRange containsA = [formatStringForHours rangeOfString:@"a"]; BOOL hasAMPM = containsA.location != NSNotFound; if (!hasAMPM) { //24小时制 if (hour <= 24 && hour >= 0) { dateFormatter = [NSDate dateFormatterWithFormat:@"HH:mm"]; }else if (hour < 0 && hour >= -24) { dateFormatter = [NSDate dateFormatterWithFormat:@"昨天HH:mm"]; }else { dateFormatter = [NSDate dateFormatterWithFormat:@"yyyy-MM-dd HH:mm"]; } }else { if (hour >= 0 && hour <= 6) { dateFormatter = [NSDate dateFormatterWithFormat:@"凌晨hh:mm"]; }else if (hour > 6 && hour <=11 ) { dateFormatter = [NSDate dateFormatterWithFormat:@"上午hh:mm"]; }else if (hour > 11 && hour <= 17) { dateFormatter = [NSDate dateFormatterWithFormat:@"下午hh:mm"]; }else if (hour > 17 && hour <= 24) { dateFormatter = [NSDate dateFormatterWithFormat:@"晚上hh:mm"]; }else if (hour < 0 && hour >= -24){ dateFormatter = [NSDate dateFormatterWithFormat:@"昨天HH:mm"]; }else { dateFormatter = [NSDate dateFormatterWithFormat:@"yyyy-MM-dd HH:mm"]; } } ret = [dateFormatter stringFromDate:self]; return ret; } /** * @brief 格式化日期描述 * * @param paramete 请求参数 * * @return NSString格式的请求参数 */ - (NSString *)formattedDateDescription { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@"yyyy-MM-dd"]; NSString *theDay = [dateFormatter stringFromDate:self];//日期的年月日 NSString *currentDay = [dateFormatter stringFromDate:[NSDate date]];//当前年月日 NSInteger timeInterval = -[self timeIntervalSinceNow]; if (timeInterval < 60) { return @"1分钟内"; } else if (timeInterval < 3600) {//1小时内 return [NSString stringWithFormat:@"%ld分钟前", (long)timeInterval / 60]; } else if (timeInterval < 21600) {//6小时内 return [NSString stringWithFormat:@"%ld小时前", (long)timeInterval / 3600]; } else if ([theDay isEqualToString:currentDay]) {//当天 [dateFormatter setDateFormat:@"HH:mm"]; return [NSString stringWithFormat:@"今天 %@", [dateFormatter stringFromDate:self]]; } else if ([[dateFormatter dateFromString:currentDay] timeIntervalSinceDate:[dateFormatter dateFromString:theDay]] == 86400) {//昨天 [dateFormatter setDateFormat:@"HH:mm"]; return [NSString stringWithFormat:@"昨天 %@", [dateFormatter stringFromDate:self]]; } else {//以前 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm"]; return [dateFormatter stringFromDate:self]; } } - (double)timeIntervalSince1970InMilliSecond { double ret; ret = [self timeIntervalSince1970] * 1000; return ret; } + (NSDate *)dateWithTimeIntervalInMilliSecondSince1970:(double)timeIntervalInMilliSecond { NSDate *ret = nil; double timeInterval = timeIntervalInMilliSecond; // 判断参数是否在secconds中(对于以前的数据结构) if(timeIntervalInMilliSecond > 140000000000) { timeInterval = timeIntervalInMilliSecond / 1000; } ret = [NSDate dateWithTimeIntervalSince1970:timeInterval]; return ret; } + (NSString *)formattedTimeFromTimeInterval:(long long)time{ return [[NSDate dateWithTimeIntervalInMilliSecondSince1970:time] formattedTime]; } #pragma mark Relative Dates + (NSDate *) dateWithDaysFromNow: (NSInteger) days { return [[NSDate date] dateByAddingDays:days]; } + (NSDate *) dateWithDaysBeforeNow: (NSInteger) days { // Thanks, Jim Morrison return [[NSDate date] dateBySubtractingDays:days]; } + (NSDate *) dateTomorrow { return [NSDate dateWithDaysFromNow:1]; } + (NSDate *) dateYesterday { return [NSDate dateWithDaysBeforeNow:1]; } + (NSDate *) dateWithHoursFromNow: (NSInteger) dHours { NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_HOUR * dHours; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return newDate; } + (NSDate *) dateWithHoursBeforeNow: (NSInteger) dHours { NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_HOUR * dHours; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return newDate; } + (NSDate *) dateWithMinutesFromNow: (NSInteger) dMinutes { NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_MINUTE * dMinutes; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return newDate; } + (NSDate *) dateWithMinutesBeforeNow: (NSInteger) dMinutes { NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_MINUTE * dMinutes; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return newDate; } + (NSString *)weekdayStringValue:(NSDate*)date { NSCalendar *calendar = [NSCalendar currentCalendar]; NSInteger unitFlags = NSWeekCalendarUnit|NSWeekdayCalendarUnit; NSDateComponents *comps = [calendar components:unitFlags fromDate:date]; NSInteger weekday = [comps weekday]; switch (weekday) { case 1: return @"星期天"; break; case 2: return @"星期一"; break; case 3: return @"星期二"; break; case 4: return @"星期三"; break; case 5: return @"星期四"; break; case 6: return @"星期五"; break; case 7: return @"星期六"; break; default: break; } return nil; } #pragma mark Comparing Dates - (BOOL) isEqualToDateIgnoringTime: (NSDate *) aDate { NSDateComponents *components1 = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; NSDateComponents *components2 = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:aDate]; return ((components1.year == components2.year) && (components1.month == components2.month) && (components1.day == components2.day)); } - (BOOL) isToday { return [self isEqualToDateIgnoringTime:[NSDate date]]; } - (BOOL) isTomorrow { return [self isEqualToDateIgnoringTime:[NSDate dateTomorrow]]; } - (BOOL) isYesterday { return [self isEqualToDateIgnoringTime:[NSDate dateYesterday]]; } - (BOOL) isSameWeekAsDate: (NSDate *) aDate { NSDateComponents *components1 = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; NSDateComponents *components2 = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:aDate]; // 必须在同一周。12/31和1/1如果在同一周,都是周1 if (components1.weekOfYear != components2.weekOfYear) return NO; // 必须有一个时间间隔不到1周 return (fabs([self timeIntervalSinceDate:aDate]) < D_WEEK); } - (BOOL) isThisWeek { return [self isSameWeekAsDate:[NSDate date]]; } - (BOOL) isNextWeek { NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_WEEK; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return [self isSameWeekAsDate:newDate]; } - (BOOL) isLastWeek { NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] - D_WEEK; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return [self isSameWeekAsDate:newDate]; } - (BOOL) isSameMonthAsDate: (NSDate *) aDate { NSDateComponents *components1 = [CURRENT_CALENDAR components:NSCalendarUnitYear | NSCalendarUnitMonth fromDate:self]; NSDateComponents *components2 = [CURRENT_CALENDAR components:NSCalendarUnitYear | NSCalendarUnitMonth fromDate:aDate]; return ((components1.month == components2.month) && (components1.year == components2.year)); } - (BOOL) isThisMonth { return [self isSameMonthAsDate:[NSDate date]]; } - (BOOL) isSameYearAsDate: (NSDate *) aDate { NSDateComponents *components1 = [CURRENT_CALENDAR components:NSCalendarUnitYear fromDate:self]; NSDateComponents *components2 = [CURRENT_CALENDAR components:NSCalendarUnitYear fromDate:aDate]; return (components1.year == components2.year); } - (BOOL) isThisYear { return [self isSameYearAsDate:[NSDate date]]; } - (BOOL) isNextYear { NSDateComponents *components1 = [CURRENT_CALENDAR components:NSCalendarUnitYear fromDate:self]; NSDateComponents *components2 = [CURRENT_CALENDAR components:NSCalendarUnitYear fromDate:[NSDate date]]; return (components1.year == (components2.year + 1)); } - (BOOL) isLastYear { NSDateComponents *components1 = [CURRENT_CALENDAR components:NSCalendarUnitYear fromDate:self]; NSDateComponents *components2 = [CURRENT_CALENDAR components:NSCalendarUnitYear fromDate:[NSDate date]]; return (components1.year == (components2.year - 1)); } - (BOOL) isEarlierThanDate: (NSDate *) aDate { return ([self compare:aDate] == NSOrderedAscending); } - (BOOL) isLaterThanDate: (NSDate *) aDate { return ([self compare:aDate] == NSOrderedDescending); } - (BOOL) isInFuture { return ([self isLaterThanDate:[NSDate date]]); } - (BOOL) isInPast { return ([self isEarlierThanDate:[NSDate date]]); } #pragma mark Roles - (BOOL) isTypicallyWeekend { NSDateComponents *components = [CURRENT_CALENDAR components:NSCalendarUnitWeekday fromDate:self]; if ((components.weekday == 1) || (components.weekday == 7)) return YES; return NO; } - (BOOL) isTypicallyWorkday { return ![self isTypicallyWeekend]; } #pragma mark Adjusting Dates - (NSDate *) dateByAddingDays: (NSInteger) dDays { NSTimeInterval aTimeInterval = [self timeIntervalSinceReferenceDate] + D_DAY * dDays; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return newDate; } - (NSDate *) dateBySubtractingDays: (NSInteger) dDays { return [self dateByAddingDays: (dDays * -1)]; } - (NSDate *) dateByAddingHours: (NSInteger) dHours { NSTimeInterval aTimeInterval = [self timeIntervalSinceReferenceDate] + D_HOUR * dHours; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return newDate; } - (NSDate *) dateBySubtractingHours: (NSInteger) dHours { return [self dateByAddingHours: (dHours * -1)]; } - (NSDate *) dateByAddingMinutes: (NSInteger) dMinutes { NSTimeInterval aTimeInterval = [self timeIntervalSinceReferenceDate] + D_MINUTE * dMinutes; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; return newDate; } - (NSDate *) dateBySubtractingMinutes: (NSInteger) dMinutes { return [self dateByAddingMinutes: (dMinutes * -1)]; } - (NSDate *) dateAtStartOfDay { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; components.hour = 0; components.minute = 0; components.second = 0; return [CURRENT_CALENDAR dateFromComponents:components]; } - (NSDateComponents *) componentsWithOffsetFromDate: (NSDate *) aDate { NSDateComponents *dTime = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:aDate toDate:self options:0]; return dTime; } #pragma mark Retrieving Intervals - (NSInteger) minutesAfterDate: (NSDate *) aDate { NSTimeInterval ti = [self timeIntervalSinceDate:aDate]; return (NSInteger) (ti / D_MINUTE); } - (NSInteger) minutesBeforeDate: (NSDate *) aDate { NSTimeInterval ti = [aDate timeIntervalSinceDate:self]; return (NSInteger) (ti / D_MINUTE); } - (NSInteger) hoursAfterDate: (NSDate *) aDate { NSTimeInterval ti = [self timeIntervalSinceDate:aDate]; return (NSInteger) (ti / D_HOUR); } - (NSInteger) hoursBeforeDate: (NSDate *) aDate { NSTimeInterval ti = [aDate timeIntervalSinceDate:self]; return (NSInteger) (ti / D_HOUR); } - (NSInteger) daysAfterDate: (NSDate *) aDate { NSTimeInterval ti = [self timeIntervalSinceDate:aDate]; return (NSInteger) (ti / D_DAY); } - (NSInteger) daysBeforeDate: (NSDate *) aDate { NSTimeInterval ti = [aDate timeIntervalSinceDate:self]; return (NSInteger) (ti / D_DAY); } - (NSInteger)distanceInDaysToDate:(NSDate *)anotherDate { NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay fromDate:self toDate:anotherDate options:0]; return components.day; } #pragma mark Decomposing Dates - (NSInteger) nearestHour { NSTimeInterval aTimeInterval = [[NSDate date] timeIntervalSinceReferenceDate] + D_MINUTE * 30; NSDate *newDate = [NSDate dateWithTimeIntervalSinceReferenceDate:aTimeInterval]; NSDateComponents *components = [CURRENT_CALENDAR components:NSCalendarUnitHour fromDate:newDate]; return components.hour; } - (NSInteger) hour { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.hour; } - (NSInteger) minute { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.minute; } - (NSInteger) seconds { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.second; } - (NSInteger) day { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.day; } - (NSInteger) month { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.month; } - (NSInteger) week { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.weekOfYear; } - (NSInteger) weekday { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.weekday; } - (NSInteger) nthWeekday // e.g. 2nd Tuesday of the month is 2 { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.weekdayOrdinal; } - (NSInteger) year { NSDateComponents *components = [CURRENT_CALENDAR components:DATE_COMPONENTS fromDate:self]; return components.year; } #pragma mark 格式化日期 + (id)dateFormatter { return [[self alloc] init]; } + (id)dateFormatterWithFormat:(NSString *)dateFormat { NSDateFormatter *dateFormatter = [[self alloc] init]; dateFormatter.dateFormat = dateFormat; return dateFormatter; } + (id)defaultDateFormatter { return [self dateFormatterWithFormat:@"yyyy-MM-dd HH:mm:ss"]; } @end
posted on 2018-02-24 13:16 东方🐺 阅读(632) 评论(4) 编辑 收藏 举报