前言:
由于查詢數(shù)據(jù)庫時查詢條件需要傳遞日期來獲取某個月份的數(shù)據(jù)列表,如果傳的時該月的某一天會導(dǎo)致拿到數(shù)據(jù)不全,如果傳了該月的第一天會導(dǎo)致拿到的數(shù)據(jù)并不是當(dāng)月的;而如果剛好查詢當(dāng)前月份的數(shù)據(jù)是不能用這個月的最后一天只能用當(dāng)天來查詢,于是有了以下的日歷操作
- 首先,想要直接得到某個日期的NSDate,可以通過dateWithTimeInterval,與某個日期的毫秒差來獲取,但是這個方法前提是需要知道基點(diǎn)日期,就算以當(dāng)前的Date來計算,毫秒的計算也得自己去寫清楚;比較麻煩,這時候可以通過日歷對象的NSDateComponents來方便地定制指定日期,以下是兩個NSDate分類方法
//這個方法可以獲取某個與當(dāng)前NSDate對象指定間隔的日期
//這里傳的year.month 等都可以有正負(fù),正數(shù)表示該日期之后的,負(fù)數(shù)表示該日期之前
- (instancetype)getDateFromDateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hours:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second{
//創(chuàng)建一個工具,一個封裝了具體年月日、時秒分、周、季度等的類
// NSDateComponents* dateComponents = [[NSDateComponents alloc]init];
NSDateComponents* dateComponents;
//創(chuàng)建一個日歷,它提供了大部分的日期計算接口,并且允許在NSDate和NSDateComponents之間轉(zhuǎn)換
NSCalendar *dateCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
// NSDate 轉(zhuǎn) NSDateComponents所需要設(shè)置的值,可根據(jù)需要自己設(shè)置,這里是年~秒全部獲取,如果某個沒有寫的話,比如NSCalendarUnitHour,轉(zhuǎn)成NSDateComponents后,會是一個很大或很小的數(shù)
NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitWeekday | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
//為dateComponents獲取值,該值等價于self的各個部件
dateComponents = [dateCalendar components:unitFlags fromDate:self];
//創(chuàng)建一個NSDateComponents,開始設(shè)置想要的時間
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設(shè)置的值轉(zhuǎn)為NSDate格式,這個NSDate就是想要的時間
NSDate *myDate = [dateCalendar dateFromComponents:myCompoentes];
return myDate;
}
//這個方法可以直接更改某個日期的某個組件 參數(shù)傳-1表示不改變
- (instancetype)setDateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hours:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second{
//創(chuàng)建一個工具,一個封裝了具體年月日、時秒分、周、季度等的類
NSDateComponents* dateComponents;
//創(chuàng)建一個日歷,它提供了大部分的日期計算接口,并且允許在NSDate和NSDateComponents之間轉(zhuǎn)換
NSCalendar *dateCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
dateComponents = [dateCalendar components:unitFlags fromDate:self];
//創(chuàng)建一個NSDateComponents,開始設(shè)置想要的時間
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設(shè)置的值轉(zhuǎn)為NSDate格式,這個NSDate就是想要的時間
NSDate *myDate = [dateCalendar dateFromComponents:myCompoentes];
return myDate;
}
- 接下來要分析如何得到某個月份的最后一天,由于每個月的天數(shù)的不一樣,還有2月這個特殊存在,不好使用窮盡判斷的方式來設(shè)置.這時候就想到日歷對象對日期的操作,結(jié)合上面兩個方法,輕而易舉的就實(shí)現(xiàn)了
- (NSDate *)getMonthLastDate{
//先設(shè)置為1號,因?yàn)楸热?0月份如果是剛好是31號然后讓它月份+1,會導(dǎo)致得到的日期變成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];
//最后讓已經(jīng)是1號的NSDate天數(shù)-1, 就得到了本月的最后一天了
NSDate *monthLastDate = [nextMonthDate getDateFromDateWithYear:0 month:0 day:-1 hours:0 minute:0 second:0];
return monthLastDate;
}
- 這里有個小插曲,就是如果需要拿當(dāng)前月份的數(shù)據(jù)的時候,不能傳這個月的最后一天,只能傳當(dāng)前Date,因此需要判斷NSDate是否是當(dāng)月
- (BOOL)isThisMonth
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth;
// 獲得某個時間的年月
NSDateComponents *dateCmps = [calendar components:unit fromDate:self];
//與當(dāng)前日期比較
NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
return dateCmps.year == nowCmps.year && dateCmps.month == nowCmps.month;
}
- 如果需要判斷得到的日期是否是周末
- (BOOL)isWeekend{
//計算week數(shù)
NSCalendar * myCalendar = [NSCalendar currentCalendar];
myCalendar.timeZone = [NSTimeZone systemTimeZone];
NSInteger week = [[myCalendar components:NSCalendarUnitWeekday fromDate:self] weekday];
//國際日期中1是周日 7是周六 , 其他2~6對應(yīng)星期一~星期五
switch (week) {
case 1: { return YES; }
case 7: { return YES; }
default: { return NO; }
}
}