日历(iOS)阳历+农历

效果如动图:


日历.gif

传入年份,返回给你一年的数据:

//调用的接口
- (NSMutableArray *)getNumberOfDaysInMonthByYear:(NSString *)whichYear;

实现的具体代码:

// 获取一年中每月的总天数
- (NSMutableArray *)getNumberOfDaysInMonthByYear:(NSString *)whichYear
{
NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; // 指定日历的算法
NSDateFormatter * formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd"];
NSMutableArray *allYaerMonthDayCountArray = [[NSMutableArray alloc] init];

for (int j=0; j<12; j++) {
    NSMutableDictionary *dicM = [[NSMutableDictionary alloc] init];
    NSString * dateStr = [NSString stringWithFormat:@"%@-%02d-01",whichYear,j+1];
    NSDate * currentDate = [formatter dateFromString:dateStr];
    NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay
                                   inUnit: NSCalendarUnitMonth
                                  forDate:currentDate];
    
    [formatter setDateFormat:@"yyyy-MM"];
    NSString * str = [formatter stringFromDate:currentDate];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSMutableArray * allDaysArray = [[NSMutableArray alloc] init];
    for (NSInteger i = 1; i <= range.length; i++) {
        NSString * sr = [NSString stringWithFormat:@"%@-%ld",str,i];
        NSDate *suDate = [formatter dateFromString:sr];
        [allDaysArray addObject:[self getweekDayWithDate:suDate]];
    }
    
    [dicM setObject:@(range.length) forKey:@"monthAllDayCount"];
    [dicM setObject:allDaysArray forKey:@"monthWeekArray"];
    [allYaerMonthDayCountArray addObject:dicM];
}

return allYaerMonthDayCountArray;
}

/**
 *  获得某天的数据
 *
 *  获取指定的日期是星期几
 */
- (id) getweekDayWithDate:(NSDate *) date
{
NSCalendar * calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; // 指定日历的算法
NSDateComponents *comps = [calendar components:NSCalendarUnitWeekday fromDate:date];
// 1 是周日,2是周一 3.以此类推
return @([comps weekday]);

}

返回的数据结构如下图:


返回的数据结构.png

上面的这些都是处理阳历数据,如果需要显示农历和对应的节假日什么的,也提供了一个接口,

// 获取date当天的农历
-(NSString*)getChineseCalendarWithDate:(NSString*)date;

需要传入"2017-01-01"这样的日期字符串。具体代码如下:

-(NSString*)getChineseCalendarWithDate:(NSString*)date{
NSArray *chineseYears = [NSArray arrayWithObjects:
                         @"甲子", @"乙丑", @"丙寅", @"丁卯",  @"戊辰",  @"己巳",  @"庚午",  @"辛未",  @"壬申",  @"癸酉",
                         @"甲戌",   @"乙亥",  @"丙子",  @"丁丑", @"戊寅",   @"己卯",  @"庚辰",  @"辛己",  @"壬午",  @"癸未",
                         @"甲申",   @"乙酉",  @"丙戌",  @"丁亥",  @"戊子",  @"己丑",  @"庚寅",  @"辛卯",  @"壬辰",  @"癸巳",
                         @"甲午",   @"乙未",  @"丙申",  @"丁酉",  @"戊戌",  @"己亥",  @"庚子",  @"辛丑",  @"壬寅",  @"癸丑",
                         @"甲辰",   @"乙巳",  @"丙午",  @"丁未",  @"戊申",  @"己酉",  @"庚戌",  @"辛亥",  @"壬子",  @"癸丑",
                         @"甲寅",   @"乙卯",  @"丙辰",  @"丁巳",  @"戊午",  @"己未",  @"庚申",  @"辛酉",  @"壬戌",  @"癸亥", nil];

NSArray *chineseMonths=[NSArray arrayWithObjects:
                        @"正月", @"二月", @"三月", @"四月", @"五月", @"六月", @"七月", @"八月",
                        @"九月", @"十月", @"十一月", @"腊月", nil];

NSArray *chineseDays=[NSArray arrayWithObjects:
                      @"初一", @"初二", @"初三", @"初四", @"初五", @"初六", @"初七", @"初八", @"初九", @"初十",
                      @"十一", @"十二", @"十三", @"十四", @"十五", @"十六", @"十七", @"十八", @"十九", @"二十",
                      @"廿一", @"廿二", @"廿三", @"廿四", @"廿五", @"廿六", @"廿七", @"廿八", @"廿九", @"三十",  nil];

NSDate *dateTemp = nil;
NSDateFormatter *dateFormater = [[NSDateFormatter alloc]init];
[dateFormater setDateFormat:@"yyyy-MM-dd"];
dateTemp = [dateFormater dateFromString:date];
NSCalendar *localeCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierChinese];
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
NSDateComponents *localeComp = [localeCalendar components:unitFlags fromDate:dateTemp];
 //   NSLog(@"%ld_%ld_%ld  %@",(long)localeComp.year,(long)localeComp.month,(long)localeComp.day, localeComp.date);
NSString *y_str = [chineseYears objectAtIndex:localeComp.year-1];
NSString *m_str = [chineseMonths objectAtIndex:localeComp.month-1];
NSString *d_str = [chineseDays objectAtIndex:localeComp.day-1];
NSString *chineseCal_str =nil;
NSString *choose_str = [NSString stringWithFormat: @"%@%@",m_str,d_str];
NSString *riqi_str = [date substringWithRange:NSMakeRange(5, 5)];
if ([d_str isEqualToString:@"初一"]) {
    chineseCal_str =[NSString stringWithFormat: @"%@",m_str];
}else{
    if ([riqi_str isEqualToString:@"01-01"]) {
        chineseCal_str = @"元旦节";
    }else if([riqi_str isEqualToString:@"04-01"]){
        chineseCal_str = @"愚人节";
    }else if([riqi_str isEqualToString:@"05-01"]){
        chineseCal_str = @"劳动节";
    }else if([riqi_str isEqualToString:@"06-01"]){
        chineseCal_str = @"儿童节";
    }else if([riqi_str isEqualToString:@"07-01"]){
        chineseCal_str = @"建军节";
    }else if([riqi_str isEqualToString:@"08-01"]){
        chineseCal_str = @"建党节";
    }else if([riqi_str isEqualToString:@"09-10"]){
        chineseCal_str = @"教师节";
    }else if([riqi_str isEqualToString:@"10-01"]){
        chineseCal_str = @"国庆节";
    }else if([riqi_str isEqualToString:@"12-25"]){
        chineseCal_str = @"圣诞节";
    }else if ([choose_str isEqualToString:@"腊月三十"]) {
        chineseCal_str = @"除夕夜";
    }else if ([choose_str isEqualToString:@"正月十五"]){
        chineseCal_str =@"元宵节";
    }else if ([choose_str isEqualToString:@"二月初二"]){
        chineseCal_str =@"龙头节";
    }else if ([choose_str isEqualToString:@"三月初八"]){
        chineseCal_str =@"清明节";
    }else if ([choose_str isEqualToString:@"五月初五"]){
        chineseCal_str =@"端午节";
    }else if ([choose_str isEqualToString:@"八月十五"]){
        chineseCal_str =@"中秋节";
    }else{
        chineseCal_str =[NSString stringWithFormat: @"%@",d_str];
    }
}
return chineseCal_str;
}

数据准备就这些,下面就是如何处理并显示的问题了。
这个demo采用的是collectioncell显示的,数据中两个比较关键的值一个是当月共多少天,一个是当月第一天是周几。因为collectioncell在显示的时候从左至右一排一排排列的,但是不可能每月的一号都在第一个位置,我做的处理是,根据当月第一天是周几,collectioncell从第几个indexpath.row+1-周几 的那个位置开始显示,cell的数量顺序增加周几个数。

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
LFCalendarCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"LFCalendarCollectionViewCell" forIndexPath:indexPath];
LFCanlendarModel *model = self.sourceDataArray[indexPath.section];
NSArray *arr = model.monthWeekArray;
NSInteger number = indexPath.row+1-[arr[0] integerValue];
if (number>=0) {
    [cell setCellStylebyIndexPath:indexPath withNowInteger:number+1 withYear:yearStr];
}else{
    [cell setCellStylebyIndexPath:indexPath withNowInteger:0  withYear:yearStr];
}
return cell;
}

需要代码的可以去https://github.com/marsLiuFei/CalendarDemo 进行下载。代码不是很严谨,但总体效果能实现。如果有好的修改方案,还希望在GitHub给予fork修改。共同学习,谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容