前言:
由于查询数据库时查询条件需要传递日期来获取某个月份的数据列表,如果传的时该月的某一天会导致拿到数据不全,如果传了该月的第一天会导致拿到的数据并不是当月的;而如果刚好查询当前月份的数据是不能用这个月的最后一天只能用当天来查询,于是有了以下的日历操作
- 首先,想要直接得到某个日期的NSDate,可以通过dateWithTimeInterval,与某个日期的毫秒差来获取,但是这个方法前提是需要知道基点日期,就算以当前的Date来计算,毫秒的计算也得自己去写清楚;比较麻烦,这时候可以通过日历对象的NSDateComponents来方便地定制指定日期,以下是两个NSDate分类方法
//这个方法可以获取某个与当前NSDate对象指定间隔的日期
//这里传的year.month 等都可以有正负,正数表示该日期之后的,负数表示该日期之前
- (instancetype)getDateFromDateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hours:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second{
//创建一个工具,一个封装了具体年月日、时秒分、周、季度等的类
// NSDateComponents* dateComponents = [[NSDateComponents alloc]init];
NSDateComponents* dateComponents;
//创建一个日历,它提供了大部分的日期计算接口,并且允许在NSDate和NSDateComponents之间转换
NSCalendar *dateCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
// NSDate 转 NSDateComponents所需要设置的值,可根据需要自己设置,这里是年~秒全部获取,如果某个没有写的话,比如NSCalendarUnitHour,转成NSDateComponents后,会是一个很大或很小的数
NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitWeekday | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
//为dateComponents获取值,该值等价于self的各个部件
dateComponents = [dateCalendar components:unitFlags fromDate:self];
//创建一个NSDateComponents,开始设置想要的时间
NSDateComponents *myCompoentes = [[NSDateComponents alloc]init];
[myCompoentes setYear:dateComponents.year + year];
[myCompoentes setMonth:dateComponents.month + month];
[myCompoentes setDay:dateComponents.day + day];
[myCompoentes setHour:dateComponents.hour + hour];
[myCompoentes setMinute:dateComponents.minute + minute];
[myCompoentes setSecond:dateComponents.second + second];
//把通过myCompoentes设置的值转为NSDate格式,这个NSDate就是想要的时间
NSDate *myDate = [dateCalendar dateFromComponents:myCompoentes];
return myDate;
}
//这个方法可以直接更改某个日期的某个组件 参数传-1表示不改变
- (instancetype)setDateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hours:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second{
//创建一个工具,一个封装了具体年月日、时秒分、周、季度等的类
NSDateComponents* dateComponents;
//创建一个日历,它提供了大部分的日期计算接口,并且允许在NSDate和NSDateComponents之间转换
NSCalendar *dateCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
dateComponents = [dateCalendar components:unitFlags fromDate:self];
//创建一个NSDateComponents,开始设置想要的时间
NSDateComponents *myCompoentes = [[NSDateComponents alloc]init];
year != -1 ? [myCompoentes setYear:year] : [myCompoentes setYear:dateComponents.year];
month != -1 ? [myCompoentes setMonth:month] : [myCompoentes setMonth:dateComponents.month];
day != -1 ? [myCompoentes setDay:day] : [myCompoentes setDay:dateComponents.day];
hour != -1 ? [myCompoentes setHour:hour] : [myCompoentes setHour:dateComponents.hour];
minute != -1 ? [myCompoentes setMinute: minute : [myCompoentes setMinute:dateComponents.minute];
second != -1 ? [myCompoentes setSecond:second] : [myCompoentes setSecond:dateComponents.second];
//把通过myCompoentes设置的值转为NSDate格式,这个NSDate就是想要的时间
NSDate *myDate = [dateCalendar dateFromComponents:myCompoentes];
return myDate;
}
- 接下来要分析如何得到某个月份的最后一天,由于每个月的天数的不一样,还有2月这个特殊存在,不好使用穷尽判断的方式来设置.这时候就想到日历对象对日期的操作,结合上面两个方法,轻而易举的就实现了
- (NSDate *)getMonthLastDate{
//先设置为1号,因为比如10月份如果是刚好是31号然后让它月份+1,会导致得到的日期变成12月的1号而不是11月30号
NSDate *firstDate = [self setDateWithYear:-1 month:-1 day:1 hours:0 minute:0 second:0];
//再让月份+1 ,这样就得到了下个月的1号
NSDate *nextMonthDate = [firstDate getDateFromDateWithYear:0 month:1 day:0 hours:0 minute:0 second:0];
//最后让已经是1号的NSDate天数-1, 就得到了本月的最后一天了
NSDate *monthLastDate = [nextMonthDate getDateFromDateWithYear:0 month:0 day:-1 hours:0 minute:0 second:0];
return monthLastDate;
}
- 这里有个小插曲,就是如果需要拿当前月份的数据的时候,不能传这个月的最后一天,只能传当前Date,因此需要判断NSDate是否是当月
- (BOOL)isThisMonth
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth;
// 获得某个时间的年月
NSDateComponents *dateCmps = [calendar components:unit fromDate:self];
//与当前日期比较
NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
return dateCmps.year == nowCmps.year && dateCmps.month == nowCmps.month;
}
- 如果需要判断得到的日期是否是周末
- (BOOL)isWeekend{
//计算week数
NSCalendar * myCalendar = [NSCalendar currentCalendar];
myCalendar.timeZone = [NSTimeZone systemTimeZone];
NSInteger week = [[myCalendar components:NSCalendarUnitWeekday fromDate:self] weekday];
//国际日期中1是周日 7是周六 , 其他2~6对应星期一~星期五
switch (week) {
case 1: { return YES; }
case 7: { return YES; }
default: { return NO; }
}
}