// // YMCalendarUtils.m // MSYOUPAI // // Created by YoMi on 2024/3/3. // Copyright © 2024 MS. All rights reserved. // #import "YMCalendarUtils.h" @interface YMCalendarUtils () @property (nonatomic, strong) NSCalendar *calendar; @property (nonatomic, strong) NSCalendar *currentCalendar; @property (nonatomic, strong) NSCalendar *chineseCalendar; @property (nonatomic, strong) NSCalendar *gregorianCalendar; @end @implementation YMCalendarUtils #pragma mark -- 单例 static YMCalendarUtils *_instance; + (instancetype)allocWithZone:(struct _NSZone *)zone { // 也可以使用一次性代码 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (_instance == nil) { _instance = [super allocWithZone:zone]; } }); return _instance; } + (instancetype)shareCalender { return [[self alloc]init]; } - (id)copyWithZone:(NSZone *)zone { return _instance; } - (id)mutableCopyWithZone:(NSZone *)zone { return _instance; } - (NSCalendar *)gregorianCalendar { if (!_gregorianCalendar) { _gregorianCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; } return _gregorianCalendar; } - (NSCalendar *)currentCalendar { if (!_currentCalendar) { _currentCalendar = [NSCalendar currentCalendar]; } return _currentCalendar; } - (NSCalendar *)chineseCalendar{ if (!_chineseCalendar) { _chineseCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierChinese]; } return _chineseCalendar; } #pragma mark --与农历相关 - (NSString *)calendarIdentifierChineseWithDate:(NSDate *)date { NSString *chineseDateStr = @""; NSCalendarUnit unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear; NSDateComponents *com = [self.chineseCalendar components:unit fromDate:date]; NSInteger day = com.day; NSInteger month = com.month; NSInteger year = com.year; chineseDateStr = [NSString stringWithFormat:@"%ld-%ld-%ld",(long)year,(long)month,(long)day]; return chineseDateStr; } #pragma mark -- 与NSCalendar相关 // 获取当前月份的天数 - (NSInteger)getCurrentMonthForDays { NSInteger dayNumber = 0; NSRange range = [self.currentCalendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:[NSDate date]]; dayNumber = range.length; return dayNumber; } // 获取目标月份的天数 - (NSInteger)getNextNMonthForDays:(NSDate *)date{ NSCalendar * calendar = [NSCalendar currentCalendar]; // 调用rangeOfUnit方法:(返回一样是一个结构体)两个参数一个大单位,一个小单位(.length就是天数,.location就是月) NSInteger monthNum = [calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date].length; return monthNum; } - (NSInteger)getSumOfDaysForYear:(NSString *)year month:(NSString *)month { NSDateFormatter * formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"yyyy-MM"]; // 年-月 NSString * dateStr = [NSString stringWithFormat:@"%@-%@",year,month]; NSDate * date = [formatter dateFromString:dateStr]; // NSCalendar * calendar = self.gregorianCalendar; NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit: NSCalendarUnitMonth forDate:date]; return range.length; } // 获取某个月的1号的 date 对象 - (NSDate *)getAMonthframDate:(NSDate*)date { NSCalendar * calendar = [NSCalendar currentCalendar]; // 指定日历单位,如日期和月份。(这里指定了年月日,还有其他字段添加单位.特别齐全 :世纪,年月日时分秒等等等) NSCalendarUnit dayInfoUnits = NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay; // NSDateComponents封装了日期的组件,年月日时分秒等(个人感觉像是平时用的model模型) NSDateComponents *components = [calendar components: dayInfoUnits fromDate:date]; // 指定1号 components.day = 1; // 转成需要的date对象return NSDate * nextMonthDate =[calendar dateFromComponents:components]; return nextMonthDate; } // 获取某个月的1号是星期几 - (NSString *)getFirstDayWeekForMonth:(NSDate *)date { NSInteger weekDay = 0; NSArray *weekStr = @[@"星期日",@"星期一",@"星期二",@"星期三",@"星期四",@"星期五",@"星期六"]; //获取公历日历 NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; weekDay = components.weekday; weekDay--; return weekStr[weekDay]; } // 获取某个月的某天是星期几 - (NSUInteger )getFirstDayWeekIntergerForMonth:(NSDate *)date{ NSUInteger weekDay = 0; // NSArray *weekStr = @[@"星期日",@"星期一",@"星期二",@"星期三",@"星期四",@"星期五",@"星期六"]; //获取公历日历 NSCalendar *calendar = self.gregorianCalendar; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; weekDay = components.weekday; weekDay--; return weekDay; } #pragma mark -- 与时间NSDate相关 - (NSString *)getCurrentTimeWithHourMinSecond:(BOOL)flag{ NSDateFormatter * formatter = [[NSDateFormatter alloc]init]; // 格式化系统时间字符串 if (flag) { [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; } else { [formatter setDateFormat:@"yyyy-MM-dd"]; } NSString * time = [formatter stringFromDate:[NSDate date]]; return time; } - (int)getYear{ NSCalendar *calendar = self.currentCalendar; NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]]; return (int)dateComponent.year; } - (int)getMonth{ NSCalendar *calendar = self.currentCalendar; NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]]; return (int)dateComponent.month; } - (int)getDay{ NSCalendar *calendar = self.currentCalendar; NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]]; return (int)dateComponent.day; } - (int)getHour{ NSCalendar *calendar = self.currentCalendar; NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]]; return (int)dateComponent.hour; } - (int)getMinute{ NSCalendar *calendar = self.currentCalendar; NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]]; return (int)dateComponent.minute; } - (int)getSecond{ NSCalendar *calendar = self.currentCalendar; NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond; NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:[NSDate date]]; return (int)dateComponent.second; } - (NSInteger)getYearWithDate:(NSDate *)date{ NSCalendar *calendar = self.gregorianCalendar; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; return components.year; } - (NSInteger)getMonthWithDate:(NSDate *)date{ NSCalendar *calendar = self.gregorianCalendar; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; return components.month; } - (NSInteger)getDayWithDate:(NSDate *)date{ NSCalendar *calendar = self.gregorianCalendar; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; return components.day; } - (NSInteger)getHourWithDate:(NSDate *)date{ NSCalendar *calendar = self.gregorianCalendar; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; return components.hour; } - (NSInteger)getMinuteWithDate:(NSDate *)date{ NSCalendar *calendar = self.gregorianCalendar; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; return components.minute; } - (NSInteger)getSecondWithDate:(NSDate *)date{ NSCalendar *calendar = self.gregorianCalendar; NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitWeekday; NSDateComponents *components = [calendar components:unit fromDate:date]; return components.second; } - (NSTimeInterval )timeIntervalWithDateStr:(NSString *)dateStr dateStrFormatterStr:(NSString *)formatterStr { NSDate *date = [self dateWithDateStr:dateStr dateStrFormatterStr:formatterStr]; NSTimeInterval timeInterval = [date timeIntervalSince1970]; return timeInterval; } // 字符串时间 --> NSDate - (NSDate *)dateWithDateStr:(NSString *)dateStr dateStrFormatterStr:(NSString *)formatterStr { NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; [formatter setDateFormat:formatterStr]; NSDate *date = [formatter dateFromString:dateStr]; return date; } // NSDate --> 字符串时间 - (NSString *)dateStrWithDate:(NSDate *)date dateStrFormatterStr:(NSString *)formatterStr { NSDateFormatter *formatter = [[NSDateFormatter alloc]init]; [formatter setDateFormat:formatterStr]; NSString *dateStr = [formatter stringFromDate:date]; return dateStr; } // 当前时间与指定时间的间隔 - (NSString *)getStandardTimeInterval:(NSTimeInterval)interval{ //当前时间与1970时间戳(秒为单位) NSTimeInterval time = [[NSDate date] timeIntervalSince1970]; // 当前时间戳-传入的时间戳=差值(比如朋友圈动态发表时间为10分钟前(当前时间-发表时间)) NSTimeInterval timeInterval = time-interval; //计算出天、小时、分钟 int day = timeInterval/(60*60*24); int hour = ((long)timeInterval%(60*60*24))/(60*60); int minite = ((long)timeInterval%(60*60*24))%(60*60)/60; NSMutableString * timeStr = [[NSMutableString alloc]init]; // 逻辑判断 if (day!=0) { [timeStr appendString:[NSString stringWithFormat:@"%d天",day]]; }else{ if (hour!=0) { [timeStr appendString:[NSString stringWithFormat:@"%d小时",hour]]; }else{ if (minite<1) { [timeStr appendString:@"刚刚"]; }else{ [timeStr appendString:[NSString stringWithFormat:@"%d分钟",minite]]; } } } return timeStr; } // 当前时间与指定时间的间隔(返回分钟) - (NSInteger )getDifferenceMinWithTimeInterval:(NSTimeInterval)interval{ //当前时间与1970时间戳(秒为单位) NSTimeInterval time = [[NSDate date] timeIntervalSince1970]; // 当前时间戳-传入的时间戳=差值(比如朋友圈动态发表时间为10分钟前(当前时间-发表时间)) NSTimeInterval timeInterval = time - interval; // if (time > interval) { // timeInterval = fabs(time - interval); // // } else { // timeInterval = fabs(interval - time); // // } //计算分 NSInteger minite = (long)timeInterval/60; return minite; } - (NSInteger)numberOfDaysWithFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate{ NSCalendar *calendar = self.gregorianCalendar; NSDateComponents *comp = [calendar components:NSCalendarUnitDay fromDate:fromDate toDate:toDate options:NSCalendarWrapComponents]; return comp.day; } /** 计算当前日期的前一天或者后一天 @param later 是否计算后一天 @param currentDateStr 当期的日期 @return 返回计算后的字符串 */ - (NSString *)calculateMonthDay:(BOOL)later withCurrentDateStr:(NSString *)currentDateStr { NSInteger second = 0; if (later) {//后一天 second = 24*60*60; } else { second = - 24* 60 * 60; } NSCalendar *calendar = self.currentCalendar; NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init]; [inputFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]]; [inputFormatter setDateFormat:@"yyyy-MM-dd"]; NSDate *inputDate = [inputFormatter dateFromString:currentDateStr]; NSDate *nextDate = [NSDate dateWithTimeInterval:second sinceDate:inputDate]; NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekday|NSCalendarUnitDay fromDate:nextDate]; NSString *month = comps.month > 9 ? [NSString stringWithFormat:@"%ld",(long)comps.month]:[NSString stringWithFormat:@"0%ld",(long)comps.month]; NSString *day = comps.day > 9 ?[NSString stringWithFormat:@"%ld",(long)comps.day]:[NSString stringWithFormat:@"0%ld",(long)comps.day]; NSString *currentDate = [NSString stringWithFormat:@"%ld-%@-%@",(long)comps.year,month,day]; return currentDate; } /** 计算前一天或者后一天 @param later 是否是后一天 @param currentDateStr 要计算的日期 @return 返回的日期字典key:year、month、day */ - (NSDictionary *)calculateDate:(BOOL)later withCurrentDateStr:(NSString *)currentDateStr { NSInteger second = 0; if (later) {//后一天 second = 24*60*60; } else { second = -24*60*60; } NSCalendar *calendar = self.currentCalendar; NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init]; [inputFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]]; [inputFormatter setDateFormat:@"yyyy-MM-dd"]; NSDate *inputDate = [inputFormatter dateFromString:currentDateStr]; NSDate *nextDate = [NSDate dateWithTimeInterval:second sinceDate:inputDate]; NSDateComponents *comps = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitWeekday|NSCalendarUnitDay fromDate:nextDate]; NSString *month = comps.month > 9 ? [NSString stringWithFormat:@"%ld",(long)comps.month]:[NSString stringWithFormat:@"0%ld",(long)comps.month]; NSString *day = comps.day > 9 ?[NSString stringWithFormat:@"%ld",(long)comps.day]:[NSString stringWithFormat:@"0%ld",(long)comps.day]; NSDictionary *resultDic = @{@"year":@(comps.year),@"month":month,@"day":day}; return resultDic; } - (BOOL)isTodayWithDate:(NSDate *)date{ NSCalendar *calendar = [NSCalendar currentCalendar]; int unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear; // 1.获得当前时间的年月日 NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]]; // 2.获得self的年月日 NSDateComponents *selfCmps = [calendar components:unit fromDate:date]; return (selfCmps.year == nowCmps.year) && (selfCmps.month == nowCmps.month) && (selfCmps.day == nowCmps.day); } /** 获取 当前时间的时间戳 @return 返回的时间戳 */ - (NSTimeInterval )currentTimeInterval { return [self timeIntervalWithDateStr:[self getCurrentTimeWithHourMinSecond:YES] dateStrFormatterStr:@"yyyy-MM-dd HH:mm:ss"]; } @end