当我们在Mac下打开终端,然后输入以下命令:看看会发生什么?
(1)cal:输出当年当月的日历;
。
(2)cal 1 2016 :输出指定年份和月份的日历;
。
(3)cal 2015 :输出该年的日历;
。
(4)cal -m 10 :输出当年指定月份的日历;
。
可以看到,cal命令是Mac下查看日历(Calendar)的一个命令,使用起来非常的方便,现在我们使用Objective-C来实现这个控制台程序,要实现一模一样的效果。下面我可能贴的代码有点多,程序我已经上传 https://github.com/chenyufeng1991/Calendar 。有些实现部分可能略显繁琐冗余,大家有兴趣也可以优化或者重构一下。
首先这个程序最重要也是最难的部分就是输出格式的问题,输出格式必须和Mac程序保持一致,这个难度会比较大。然后就是如何计算某一天是星期几?我们可以查到第一年的第一天刚好是星期六,所以我们可以计算出任何一天是星期几,当然中间会涉及到闰年的判断。其中最主要的一个计算方式就是就算某年的第一天距离第一年的第一天中间隔了多少天。
输出单单一个月的日历会比较简单,输出整个年份又会提升一个难度。因为一年的日历每一行将会输出三个月,总共输出四行。我这里采取的方式是一行一行输入:一月二月三月一起输出第一行,一月二月三月输出第二行。。。感觉就像是印刷一样。说的比较单调,我们直接通过代码来实现。
(0)注意:该程序的输入使用了main函数中的argc ,argv 两个参数。前者表示输入参数的数量,后者是一个数组,数组元素表示每一个输入参数。所以在运行本程序时,需要把Products 组下的可执行文件在Finder中打开,然后把该文件直接拖入到终端下运行即可。运行效果应该是和Mac自带的日历是一样的。输出格式也是根据终端来设计的,所以请不要直接在Xcode控制台下进行输入输出。
(1)YearAndMonthNow.h 获取当前的年份和月份
#import <Foundation/Foundation.h>
@interface YearAndMonthNow : NSObject
@property(nonatomic) int yearNow;
@property(nonatomic) int monthNow;
- (void) yearAndMonth;
@end
(2)YearAndMonthNow.m 获取当前的年份和月份实现
/*
这个类是获取当前的年份和月份;
*/
#import "YearAndMonthNow.h"
@implementation YearAndMonthNow
- (void) yearAndMonth{
NSDate *date = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
//这句是说你要获取日期的元素有哪些。获取年就要写NSYearCalendarUnit,获取小时就要写NSHourCalendarUnit,中间用|隔开;
unsigned int unitFlags = NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay;
//把要从date中获取的unitFlags标示的日期元素存放在NSDateComponents类型的d里面;
NSDateComponents *d = [cal components:unitFlags fromDate:date];
_yearNow = (int)[d year];
_monthNow = (int)[d month];
// NSLog(@"%d",_yearNow);
// NSLog(@"%d",_monthNow);
}
@end
(3)JudgeNumberRegex.h 判断用户输入的数字正确性
#import <Foundation/Foundation.h>
@interface JudgeNumberRegex : NSObject
- (BOOL) isNumber:(NSString*)str;
@end
(4)JudgeNumberRegex.m 判断用户输入的数字正确性实现
#import "JudgeNumberRegex.h"
@implementation JudgeNumberRegex
- (BOOL) isNumber:(NSString*)str{
//这个是匹配数字字符串的正则表达式;
NSString *numberRegex = @"^[0-9]+$";
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", numberRegex];
BOOL isMatch = [pred evaluateWithObject:str];
if (isMatch) {
// NSLog(@"匹配");
return true;
} else {
// NSLog(@"不匹配");
return false;
}
}
@end
(5)PrintYearAndMonth.h 打印日历
#import <Foundation/Foundation.h>
@interface PrintYearAndMonth : NSObject
- (void) printmonth:(int)year yue:(int)yue;
- (void) printyear:(int)year;
@end
(6)PrintYearAndMonth.m 打印日历实现
#import "PrintYearAndMonth.h"
#import "Days.h"
@implementation PrintYearAndMonth
//MARK: - 输出每个月的日历的函数;
//输出一个月的日历;
- (void) printmonth:(int)year yue:(int)yue{
NSNumber *none = [[NSNumber alloc] initWithInt:0];
NSNumber *jan = [[NSNumber alloc] initWithInt:31];
NSNumber *febLeap = [[NSNumber alloc] initWithInt:29];
NSNumber *febNotLeap = [[NSNumber alloc] initWithInt:28];
NSNumber *mar = [[NSNumber alloc] initWithInt:31];
NSNumber *apr = [[NSNumber alloc] initWithInt:30];
NSNumber *may = [[NSNumber alloc] initWithInt:31];
NSNumber *jun = [[NSNumber alloc] initWithInt:30];
NSNumber *jul = [[NSNumber alloc] initWithInt:31];
NSNumber *aug = [[NSNumber alloc] initWithInt:31];
NSNumber *sep = [[NSNumber alloc] initWithInt:30];
NSNumber *oco = [[NSNumber alloc] initWithInt:31];
NSNumber *nov = [[NSNumber alloc] initWithInt:30];
NSNumber *dec = [[NSNumber alloc] initWithInt:31];
NSMutableArray *monthArray = [[NSMutableArray alloc] init];
if ([Days isLeapYear:year]) {
NSArray *arr = [[NSArray alloc] initWithObjects:none,jan,febLeap,mar,apr,may,jun,jul,aug,sep,oco,nov,dec, nil];
[monthArray addObjectsFromArray:arr];
} else {
NSArray *arr = [[NSArray alloc] initWithObjects:none,jan,febNotLeap,mar,apr,may,jun,jul,aug,sep,oco,nov,dec, nil];
[monthArray addObjectsFromArray:arr];
}
int day=0;
//考虑怎样使标题居中显示;
//计算一个月份日历的长度;
NSString *calendarStr = [[NSString alloc] initWithFormat:@"%@",@" Su Mo Tu We Th Fr Sa"];
//年份转化为字符串;
NSMutableString *yearStr = [[NSMutableString alloc] initWithFormat:@"%d",year];
NSMutableStri