// // NSDate+Extension.m // JKCategories (https://github.com/shaojiankui/JKCategories) // // Created by Jakey on 15/4/25. // Copyright (c) 2015年 www.skyfox.org. All rights reserved. // https://github.com/632840804/HYBNSDateExtension #import "NSDate+JKExtension.h" @implementation NSDate (JKExtension) - (NSUInteger)jk_day { return [NSDate jk_day:self]; } - (NSUInteger)jk_month { return [NSDate jk_month:self]; } - (NSUInteger)jk_year { return [NSDate jk_year:self]; } - (NSUInteger)jk_hour { return [NSDate jk_hour:self]; } - (NSUInteger)jk_minute { return [NSDate jk_minute:self]; } - (NSUInteger)jk_second { return [NSDate jk_second:self]; } + (NSUInteger)jk_day:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSDateComponents *dayComponents = [calendar components:(NSCalendarUnitDay) fromDate:date]; #else NSDateComponents *dayComponents = [calendar components:(NSDayCalendarUnit) fromDate:date]; #endif return [dayComponents day]; } + (NSUInteger)jk_month:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSDateComponents *dayComponents = [calendar components:(NSCalendarUnitMonth) fromDate:date]; #else NSDateComponents *dayComponents = [calendar components:(NSMonthCalendarUnit) fromDate:date]; #endif return [dayComponents month]; } + (NSUInteger)jk_year:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSDateComponents *dayComponents = [calendar components:(NSCalendarUnitYear) fromDate:date]; #else NSDateComponents *dayComponents = [calendar components:(NSYearCalendarUnit) fromDate:date]; #endif return [dayComponents year]; } + (NSUInteger)jk_hour:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSDateComponents *dayComponents = [calendar components:(NSCalendarUnitHour) fromDate:date]; #else NSDateComponents *dayComponents = [calendar components:(NSHourCalendarUnit) fromDate:date]; #endif return [dayComponents hour]; } + (NSUInteger)jk_minute:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSDateComponents *dayComponents = [calendar components:(NSCalendarUnitMinute) fromDate:date]; #else NSDateComponents *dayComponents = [calendar components:(NSMinuteCalendarUnit) fromDate:date]; #endif return [dayComponents minute]; } + (NSUInteger)jk_second:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSDateComponents *dayComponents = [calendar components:(NSCalendarUnitSecond) fromDate:date]; #else NSDateComponents *dayComponents = [calendar components:(NSSecondCalendarUnit) fromDate:date]; #endif return [dayComponents second]; } - (NSUInteger)jk_daysInYear { return [NSDate jk_daysInYear:self]; } + (NSUInteger)jk_daysInYear:(NSDate *)date { return [self jk_isLeapYear:date] ? 366 : 365; } - (NSTimeInterval)by_timeIntervalWithDate:(NSDate *)date{ return [self timeIntervalSinceDate:date]; } - (BOOL)jk_isLeapYear { return [NSDate jk_isLeapYear:self]; } + (BOOL)jk_isLeapYear:(NSDate *)date { NSUInteger year = [date jk_year]; if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { return YES; } return NO; } - (NSString *)jk_formatYMD { return [NSDate jk_formatYMD:self]; } + (NSString *)jk_formatYMD:(NSDate *)date { return [NSString stringWithFormat:@"%lu-%02lu-%02lu",(unsigned long)[date jk_year],(unsigned long)[date jk_month], (unsigned long)[date jk_day]]; } - (NSUInteger)jk_weeksOfMonth { return [NSDate jk_weeksOfMonth:self]; } + (NSUInteger)jk_weeksOfMonth:(NSDate *)date { return [[date jk_lastdayOfMonth] jk_weekOfYear] - [[date jk_begindayOfMonth] jk_weekOfYear] + 1; } - (NSUInteger)jk_weekOfYear { return [NSDate jk_weekOfYear:self]; } + (NSUInteger)jk_weekOfYear:(NSDate *)date { NSUInteger i; NSUInteger year = [date jk_year]; NSDate *lastdate = [date jk_lastdayOfMonth]; for (i = 1;[[lastdate jk_dateAfterDay:-7 * i] jk_year] == year; i++) { } return i; } - (NSDate *)jk_dateAfterDay:(NSUInteger)day { return [NSDate jk_dateAfterDate:self day:day]; } + (NSDate *)jk_dateAfterDate:(NSDate *)date day:(NSInteger)day { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init]; [componentsToAdd setDay:day]; NSDate *dateAfterDay = [calendar dateByAddingComponents:componentsToAdd toDate:date options:0]; return dateAfterDay; } - (NSDate *)jk_dateAfterMonth:(NSUInteger)month { return [NSDate jk_dateAfterDate:self month:month]; } + (NSDate *)jk_dateAfterDate:(NSDate *)date month:(NSInteger)month { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *componentsToAdd = [[NSDateComponents alloc] init]; [componentsToAdd setMonth:month]; NSDate *dateAfterMonth = [calendar dateByAddingComponents:componentsToAdd toDate:date options:0]; return dateAfterMonth; } - (NSDate *)jk_begindayOfMonth { return [NSDate jk_begindayOfMonth:self]; } + (NSDate *)jk_begindayOfMonth:(NSDate *)date { return [self jk_dateAfterDate:date day:-[date jk_day] + 1]; } - (NSDate *)jk_lastdayOfMonth { return [NSDate jk_lastdayOfMonth:self]; } + (NSDate *)jk_lastdayOfMonth:(NSDate *)date { NSDate *lastDate = [self jk_begindayOfMonth:date]; return [[lastDate jk_dateAfterMonth:1] jk_dateAfterDay:-1]; } - (NSUInteger)jk_daysAgo { return [NSDate jk_daysAgo:self]; } + (NSUInteger)jk_daysAgo:(NSDate *)date { NSCalendar *calendar = [NSCalendar currentCalendar]; #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 NSDateComponents *components = [calendar components:(NSCalendarUnitDay) fromDate:date toDate:[NSDate date] options:0]; #else NSDateComponents *components = [calendar components:(NSDayCalendarUnit) fromDate:date toDate:[NSDate date] options:0]; #endif return [components day]; } - (NSInteger)jk_weekday { return [NSDate jk_weekday:self]; } + (NSInteger)jk_weekday:(NSDate *)date { NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSDateComponents *comps = [gregorian components:(NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitWeekday) fromDate:date]; NSInteger weekday = [comps weekday]; return weekday; } - (NSString *)jk_dayFromWeekday { return [NSDate jk_dayFromWeekday:self]; } + (NSString *)jk_dayFromWeekday:(NSDate *)date { switch([date jk_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 @""; } - (BOOL)jk_isSameDay:(NSDate *)anotherDate { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components1 = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:self]; NSDateComponents *components2 = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay) fromDate:anotherDate]; return ([components1 year] == [components2 year] && [components1 month] == [components2 month] && [components1 day] == [components2 day]); } - (BOOL)jk_isToday { return [self jk_isSameDay:[NSDate date]]; } - (NSDate *)jk_dateByAddingDays:(NSUInteger)days { NSDateComponents *c = [[NSDateComponents alloc] init]; c.day = days; return [[NSCalendar currentCalendar] dateByAddingComponents:c toDate:self options:0]; } /** * Get the month as a localized string from the given month number * * @param month The month to be converted in string * [1 - January] * [2 - February] * [3 - March] * [4 - April] * [5 - May] * [6 - June] * [7 - July] * [8 - August] * [9 - September] * [10 - October] * [11 - November] * [12 - December] * * @return Return the given month as a localized string */ + (NSString *)jk_monthWithMonthNumber:(NSInteger)month { switch(month) { case 1: return @"January"; break; case 2: return @"February"; break; case 3: return @"March"; break; case 4: return @"April"; break; case 5: return @"May"; break; case 6: return @"June"; break; case 7: return @"July"; break; case 8: return @"August"; break; case 9: return @"September"; break; case 10: return @"October"; break; case 11: return @"November"; break; case 12: return @"December"; break; default: break; } return @""; } + (NSString *)jk_stringWithDate:(NSDate *)date format:(NSString *)format { return [date jk_stringWithFormat:format]; } - (NSString *)jk_stringWithFormat:(NSString *)format { NSDateFormatter *outputFormatter = [[NSDateFormatter alloc] init]; [outputFormatter setDateFormat:format]; [outputFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:8*3600]]; NSString *retStr = [outputFormatter stringFromDate:self]; return retStr; } + (NSDate *)jk_dateWithString:(NSString *)string format:(NSString *)format { NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init]; [inputFormatter setDateFormat:format]; NSDate *date = [inputFormatter dateFromString:string]; return date; } - (NSUInteger)jk_daysInMonth:(NSUInteger)month { return [NSDate jk_daysInMonth:self month:month]; } + (NSUInteger)jk_daysInMonth:(NSDate *)date month:(NSUInteger)month { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: return 31; case 2: return [date jk_isLeapYear] ? 29 : 28; } return 30; } - (NSUInteger)jk_daysInMonth { return [NSDate jk_daysInMonth:self]; } + (NSUInteger)jk_daysInMonth:(NSDate *)date { return [self jk_daysInMonth:date month:[date jk_month]]; } - (NSString *)jk_timeInfo { return [NSDate jk_timeInfoWithDate:self]; } + (NSString *)jk_timeInfoWithDate:(NSDate *)date { return [self jk_timeInfoWithDateString:[self jk_stringWithDate:date format:[self jk_ymdHmsFormat]]]; } + (NSString *)jk_timeInfoWithDateString:(NSString *)dateString { NSDate *date = [self jk_dateWithString:dateString format:[self jk_ymdHmsFormat]]; NSDate *curDate = [NSDate date]; NSTimeInterval time = -[date timeIntervalSinceDate:curDate]; int month = (int)([curDate jk_month] - [date jk_month]); int year = (int)([curDate jk_year] - [date jk_year]); int day = (int)([curDate jk_day] - [date jk_day]); NSTimeInterval retTime = 1.0; if (time < 3600) { // 小于一小时 retTime = time / 60; retTime = retTime <= 0.0 ? 1.0 : retTime; return [NSString stringWithFormat:@"%.0f分钟前", retTime]; } else if (time < 3600 * 24) { // 小于一天,也就是今天 retTime = time / 3600; retTime = retTime <= 0.0 ? 1.0 : retTime; return [NSString stringWithFormat:@"%.0f小时前", retTime]; } else if (time < 3600 * 24 * 2) { return @"昨天"; } // 第一个条件是同年,且相隔时间在一个月内 // 第二个条件是隔年,对于隔年,只能是去年12月与今年1月这种情况 else if ((abs(year) == 0 && abs(month) <= 1) || (abs(year) == 1 && [curDate jk_month] == 1 && [date jk_month] == 12)) { int retDay = 0; if (year == 0) { // 同年 if (month == 0) { // 同月 retDay = day; } } if (retDay <= 0) { // 获取发布日期中,该月有多少天 int totalDays = (int)[self jk_daysInMonth:date month:[date jk_month]]; // 当前天数 + (发布日期月中的总天数-发布日期月中发布日,即等于距离今天的天数) retDay = (int)[curDate jk_day] + (totalDays - (int)[date jk_day]); } return [NSString stringWithFormat:@"%d天前", (abs)(retDay)]; } else { if (abs(year) <= 1) { if (year == 0) { // 同年 return [NSString stringWithFormat:@"%d个月前", abs(month)]; } // 隔年 int month = (int)[curDate jk_month]; int preMonth = (int)[date jk_month]; if (month == 12 && preMonth == 12) {// 隔年,但同月,就作为满一年来计算 return @"1年前"; } return [NSString stringWithFormat:@"%d个月前", (abs)(12 - preMonth + month)]; } return [NSString stringWithFormat:@"%d年前", abs(year)]; } return @"1小时前"; } - (NSString *)jk_ymdFormat { return [NSDate jk_ymdFormat]; } - (NSString *)jk_hmsFormat { return [NSDate jk_hmsFormat]; } - (NSString *)jk_ymdHmsFormat { return [NSDate jk_ymdHmsFormat]; } + (NSString *)jk_ymdFormat { return @"yyyy-MM-dd"; } + (NSString *)jk_hmsFormat { return @"HH:mm:ss"; } + (NSString *)jk_ymdHmsFormat { return [NSString stringWithFormat:@"%@ %@", [self jk_ymdFormat], [self jk_hmsFormat]]; } - (NSDate *)jk_offsetYears:(int)numYears { return [NSDate jk_offsetYears:numYears fromDate:self]; } + (NSDate *)jk_offsetYears:(int)numYears fromDate:(NSDate *)fromDate { if (fromDate == nil) { return nil; } #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; #else NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; #endif NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; [offsetComponents setYear:numYears]; return [gregorian dateByAddingComponents:offsetComponents toDate:fromDate options:0]; } - (NSDate *)jk_offsetMonths:(int)numMonths { return [NSDate jk_offsetMonths:numMonths fromDate:self]; } + (NSDate *)jk_offsetMonths:(int)numMonths fromDate:(NSDate *)fromDate { if (fromDate == nil) { return nil; } #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; #else NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; #endif NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; [offsetComponents setMonth:numMonths]; return [gregorian dateByAddingComponents:offsetComponents toDate:fromDate options:0]; } - (NSDate *)jk_offsetDays:(int)numDays { return [NSDate jk_offsetDays:numDays fromDate:self]; } + (NSDate *)jk_offsetDays:(int)numDays fromDate:(NSDate *)fromDate { if (fromDate == nil) { return nil; } #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; #else NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; #endif NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; [offsetComponents setDay:numDays]; return [gregorian dateByAddingComponents:offsetComponents toDate:fromDate options:0]; } - (NSDate *)jk_offsetHours:(int)hours { return [NSDate jk_offsetHours:hours fromDate:self]; } + (NSDate *)jk_offsetHours:(int)numHours fromDate:(NSDate *)fromDate { if (fromDate == nil) { return nil; } #if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_8_0 // NSDayCalendarUnit NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; #else NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; #endif NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; [offsetComponents setHour:numHours]; return [gregorian dateByAddingComponents:offsetComponents toDate:fromDate options:0]; } @end