在linux终端里看不了日历,我不答应!代码仓库地址
一、命令行运行的效果图
如果输入的年份是目前所在年,会标注当天的日期
二、代码实现
1. 判断闰年
bool judge_leap_year(int year) {return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
2. 判断两个年份之间有多少个闰年
int judge_total_leap_years(int start_year, int end_year) {int count = 0;for (int i = start_year; i < end_year; i++) {if (judge_leap_year(i)) {count++;}}return count;
}
3. 求一个日期到基准日期的天数
int find_gap_from_year(int base_year, int year, int month, int day) {int months[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};// 先以365天乘以间隔的年数、以及日的天数int total_days = (year - base_year) * 365 + day;// 再加上间隔年之间的n个闰年的n天total_days += judge_total_leap_years(base_year, year);// 加上所有月份的天数for(int i = 1; i < month; i++) {if (i == 2 && judge_leap_year(year)) {total_days++;}total_days += months[i];}return total_days;
}
4. 求两个日期的间隔
int find_date_gap (char *start_day, char *end_day) {int year1, month1, day1, year2, month2, day2;sscanf(start_day, "%d-%d-%d", &year1, &month1, &day1);sscanf(end_day, "%d-%d-%d", &year2, &month2, &day2);// 设置一个基准年int base_year = year1;int total_start_days = find_gap_from_year(base_year, year1, month1, day1);int total_end_days = find_gap_from_year(base_year, year2, month2, day2);return total_end_days - total_start_days;
}
5. 判断输入的日期是星期几
int judge_week_day(char *now_day) {int year, month, day;sscanf(now_day, "%d-%d-%d", &year, &month, &day);// 已知1900年1月1日是星期一int total_days = find_date_gap("1900-1-1", now_day); total_days += 1; // 每个月第一天是周日,加一天对齐int week_day = total_days % 7;return week_day;
}
6. 打印日历的功能
void printf_calendar (int year, int *months, int *first_day_of_months) {// 获取当前时间time_t current_time;struct tm *time_info;time(¤t_time);time_info = localtime(¤t_time);int current_year = time_info->tm_year + 1900;int current_mon = time_info->tm_mon + 1;int current_mday = time_info->tm_mday;bool is_current_year = (current_year == year);// 打印日历int left_count, right_count; // 左、右月日历计数int left_days, right_days; // 左、右月日历的总天数int left_first_day, right_first_day; // 左、右月日历的第一天的星期数(日~六:0~6)int left_blanks, right_blanks; // 左、右月日历第一排打印空格数printf("|=====================\033[1;37mThe Calendar of Year %4d\033[0m====================|\n", year);for (int i = 1; i <= 6; i++) {printf(": \033[1;37m%2d\033[0m \033[0;32mSUN MON TUE WED THU FRI SAT\033[0m \033[1;37m%2d\033[0m \033[0;32mSUN MON TUE WED THU FRI SAT\033[0m :\n", i, i + 6);left_count = right_count = 0;left_days = months[i];right_days = months[i+6];left_blanks = left_first_day = first_day_of_months[i];right_blanks = right_first_day = first_day_of_months[i+6];// 循环转行打印日历while (left_count < left_days || right_count < right_days) {printf(": ");for(int j = 0; j <= 6; j++) {if (left_blanks > 0 || left_count >= left_days) {printf(" ");left_blanks--;}else {left_count++;if (is_current_year && current_mon == i && current_mday == left_count) {printf("\033[1;31m%3d \033[0m", left_count);}else {printf("%3d ", left_count);}}}printf(" ");for(int j = 0; j <= 6; j++) {if (right_blanks > 0 || right_count >= right_days) {printf(" ");right_blanks--;}else {right_count++;if (is_current_year && current_mon == (i+6) && current_mday == right_count) {printf("\033[1;31m[%2d]\033[0m", right_count);}else {printf("%3d ", right_count);}}}printf(":\n");}} printf("|==================================================================|\n");
}
7. 输出输入的年份的日历
void output_calendar (int year) {// 设置每个月的第一天是星期几(星期日~星期六用0~6表示)int first_day_of_months[13] = {-1};char date_str[20];for (int i = 1; i <= 12; i++) {sprintf(date_str, "%d-%d-1", year, i);first_day_of_months[i] = judge_week_day(date_str);}// 设置查询年每个月的天数int months[13] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};if (judge_leap_year(year)) {months[2] = 29;}printf_calendar(year, months, first_day_of_months);
}
8. 主函数
int main(void) {int year;printf("输入你要查询的年份日历(仅支持1900之后):");scanf("%d", &year);output_calendar(year);return 0;
}
三、配置命令运行
1. 在linux上编译C代码
gcc -o my_calendar my_calendar.c
2. 移动可执行代码到系统 PATH
mv my_calendar /usr/local/bin