命令行万年历程序

在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(&current_time);
    time_info = localtime(&current_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
3. 在任何位置使用自定义命令calendar执行

在这里插入图片描述

相关推荐

  1. 面板小程序命令工具介绍

    2024-01-01 04:24:03       33 阅读
  2. Golang使用cobra实现命令程序

    2024-01-01 04:24:03       31 阅读
  3. monorepo工程开发交互nodejs命令程序

    2024-01-01 04:24:03       34 阅读
  4. 12-输入/输出项目构建命令程序

    2024-01-01 04:24:03       28 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-01 04:24:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-01 04:24:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-01 04:24:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-01 04:24:03       18 阅读

热门阅读

  1. Django REST framework -10-自定义认证类

    2024-01-01 04:24:03       35 阅读
  2. 【WPF.NET开发】将路由事件标记为已处理和类处理

    2024-01-01 04:24:03       34 阅读
  3. 9、python-闭包

    2024-01-01 04:24:03       42 阅读
  4. 【PostgreSQL如何查看page、index的详细信息】

    2024-01-01 04:24:03       41 阅读
  5. 深入理解SqlSugar ORM框架的使用与实战

    2024-01-01 04:24:03       31 阅读
  6. 【Delphi 基础知识 8】常用的运算符

    2024-01-01 04:24:03       40 阅读
  7. 长度最小的子数组

    2024-01-01 04:24:03       37 阅读
  8. 数据库查询优化

    2024-01-01 04:24:03       39 阅读
  9. PostgreSQL | 概念 | 什么是OLTP&OLAP?

    2024-01-01 04:24:03       39 阅读
  10. 组合设计模式

    2024-01-01 04:24:03       33 阅读
  11. Ant Design Vue表单组件a-form-item-rest使用

    2024-01-01 04:24:03       39 阅读
  12. 如何将Git的语言设置为中文

    2024-01-01 04:24:03       40 阅读
  13. 腾讯云轻量应用服务器测评,2核4G5M配置3年756元

    2024-01-01 04:24:03       37 阅读
  14. 使用函数的选择法排序

    2024-01-01 04:24:03       38 阅读
  15. python的pandas数据分析处理基础学习

    2024-01-01 04:24:03       38 阅读
  16. MySQL中常用的数据类型

    2024-01-01 04:24:03       42 阅读
  17. Android获取电池充电状态是否为快充

    2024-01-01 04:24:03       37 阅读
  18. python统计学-矩估计法、极大似然估计法?

    2024-01-01 04:24:03       38 阅读
  19. Linux: memory: THP相关的一些链接

    2024-01-01 04:24:03       34 阅读