最近,公司项目中用到了日历,于是打算自己写一下,下面做一下总结。
要想实现日历,首先需要知道一个月有多少天,再需要知道每月第一天是周几,其他的也就能根据这两点计算出来了。
废话不多说,来看关键代码👇
1.初始化
NSCalendar多次初始化可能会造成性能较低,避免多次初始化,建议定义为全局变量。
//指定日历的算法
self.calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
2.获取当月天数
传入要计算的日期,以月为单位计算。
/**
获取当月的天数
*/
-(NSInteger)getNumberOfDaysInMonthWith:(NSDate*)date
{
NSRange range = [_calendar rangeOfUnit:NSCalendarUnitDay inUnit:NSCalendarUnitMonth forDate:date];
return range.length;
}
3.获取一个月中的每一天是周几
1:周日 2:周一 3:周二 4:以此类推
/**
获取每一天是周几
*/
-(id)weekdayOfMonthWith:(NSDate*)date
{
NSDateComponents *comps = [_calendar components:NSCalendarUnitWeekday fromDate:date];
//1:周日 2:周一 3:以此类推
return @([comps weekday]);
}
4.计算每月一号是周几
/**
每月一号是周几
*/
-(NSInteger)firstdayWeekOfMonth:(NSDate*)date
{
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
NSDate *currentDate = date;
[formatter setDateFormat:@"yyyy-MM"];
NSString * str = [formatter stringFromDate:currentDate];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSString *sr = [NSString stringWithFormat:@"%@-1",str];
NSDate *suDate = [formatter dateFromString:sr];
NSInteger firstDay = [[self weekdayOfMonthWith:suDate] integerValue];//每月一号是周几
return firstDay;
}
5.计算每月日历显示的行数
/**
获取一个月的行数(周数)
*/
-(NSInteger)rowsOfMonthWith:(NSDate*)date
{
NSInteger dayCount = [self numberOfDaysInMonthWith:date]; //一个月的总天数
NSInteger firstDay = [self firstdayWeekOfMonth:date]; //一个月的第一天是周几
NSInteger rows = (dayCount - (8 - firstDay)) / 7 + 1;
return (dayCount - (8 - firstDay)) % 7 > 0 ? rows + 1 : rows;
}
6.NSDate和NSDateComponents之间的转换
#pragma mark - 转换方法
-(NSDateComponents *)dateToComponents:(NSDate*)date
{
NSDateComponents *components = [_calendar components:NSCalendarUnitEra | NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:date];
return components;
}
-(NSDate *)componentsToDate:(NSDateComponents*)components
{
components.hour = 0;
components.minute = 0;
components.second = 0;
NSDate *date = [_calendar dateFromComponents:components];
return date;
}