zoukankan      html  css  js  c++  java
  • 【C语言】第一个C语言小程序 —— 日期算法和万年历

    1. 写了个万年历的功能练练手。还没有写交互的代码,只是把方法写完了。先给出头部和方法签名

    #include<stdio.h>
    
    #define DAYS_PER_WEEK 7
    #define MONTHS 12
    #define DATE_HEADER "   Sun   Mon   Tues  Wed   Thur  Fri   Sat"
    int get_days(int, int, int);   //返回从公元元年算起,某年某月某日是第几天, 用这个数字算星期几 
    int days_of_year(int, int, int);  //返回某年某月某日是当前年份第几天
    int days_of_month(int, int);  //返还某年某月有几天
    int day_of_week(int, int, int); //返回某年某月某日是星期几,星期天返回0 
    _Bool is_leap_year(int);    //返回当前年份是否为闰年
    void print_date_of_month(int, int);    // 打印某年某月的日历     

    2.从最简单的两个方法开始

    判断闰年: 能整除400的年份 或者 能整除4,但是不能整除100的年份为闰年

    //判断是不是闰年 
    _Bool is_leap_year(int year)
    {
        return (year % 400 == 0 ) || (year % 4 == 0 && year % 100 != 0);
    }

    求某年莫个月份有多少天, 主要是闰年和平年在2月份的区别,闰年2月份有29天,平年2月份28天

    //返回这个月一共有多少天 
    int days_of_month(int year, int month)
    {
        //存储平年每月的天数 
        const int  month_days[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if(2 == month && is_leap_year(year))
            return 29; // 如果是闰年2月,返回29天 
        else
            return month_days[month-1];  //正常返回 
    }

    从公元1年1月一日开始算,求某年某月某日是第几天。

    算法:1.先算整年的部分:比如2018年,完整已经过了的年份有2017个,按平年算有 2017 * 365 天,但是其中闰年是366天,每个闰年少算了一天。1至2017有几个闰年呢, 首先从闰年的定义:能整除400的年份 或者 能整除4,但是不能整除100的年份为闰年

        闰年的数量 =  整除4的数量 - 整除100的数量 + 整除400的数量 

        所以最后的结果是 2017 * 365 + 闰年的数量 + 2018年1月1日到当前日期的天数

    //返回这一天从公元元年算起是第几天
     
    int get_days(int year, int month, int day)
    {
        int days = days_of_year(year, month, day);
        int temp = year-1;
        return temp * 365 + temp / 4 - temp / 100 + temp / 400 +  days;
    }

    从当前年份1月1日算起,某年某月某日是第几天. 

      思路很简单就是累加完整月的天数 + 当月日期

     //返回这一天在当年是第几天 
    int days_of_year(int year, int month, int day)
    {
         int i;
         int days = 0;
         for(i = 1; i < month; i++)
         {
             days += days_of_month(year, i);
             
         }
         return days + day;
    }

    计算某年某月某日是星际几

      因为公元元年1月1日是星期1,所以先算出从公元元年算起,当前日期是第几天,然后对7求模,星期天的时候返回 0

    int day_of_week(int year, int month, int day)
    {
        return get_days(year, month, day) % DAYS_PER_WEEK;
     } 

    打印某年某个月的日历

    //思路就是先确定当月1号是周几,先打印1号,然后剩下的根据1号来推

    //输出某年某个月的日历 
    void print_date_of_month(int year, int month)
    {
        //打印月份,为了让月份显示居中, 打印一些空格(根据打印星期的那行大概估算一下) 
        printf("               ");
        switch(month)
        {
            case 1: printf("January
    ");    break;
            case 2: printf("February
    ");    break;
            case 3: printf("March
    ");    break;
            case 4: printf("April
    ");    break;
            case 5: printf("May
    ");    break;
            case 6: printf("June
    ");    break;
            case 7: printf("July
    ");    break;
            case 8: printf("August
    ");    break;
            case 9: printf("September
    ");    break;
            case 10: printf("October
    ");    break;
            case 11: printf("November
    ");    break;
            case 12: printf("December
    ");    break;
            default: printf("Bad input of month, please enter a right month.
    "); return;
            
        }
        //先把星期打印出来 
        printf("%s
    ", DATE_HEADER);
        
        //先求出这个月第一天星期几 
        int day_of_week = get_days(year, month, 1) % DAYS_PER_WEEK;
        
        //因为星期天是在第一个位置,所以对星期求模(求余),比如星期天,其实是第一个位置,所以它应该是 7 % 7 = 0; 
        int first = day_of_week % DAYS_PER_WEEK;
        
        //求出这个月一共有几天 
        int days = days_of_month(year, month);
        
        int i, j;
        //先打印第一天的位置 
        for(i = 0; i < first; i++) {
            printf("      ");
        }
        printf("%6d", 1);
        //如果今天是星期六,换行 
        if(first == 6)
            printf("
    ");
        
        //打印剩下的日期 
        for(i = 1; i < days; i++)
        {
            printf("%6d", i + 1);
            //如果是星期六或者是最后一天,换行 
            if((first + i) % 7 == 6 || i + 1 == days)
                printf("
    ");
        } 
    }

    .最后附上完整代码

    #include<stdio.h>
    
    #define DAYS_PER_WEEK 7
    #define MONTHS 12
    #define DATE_HEADER "   Sun   Mon   Tues  Wed   Thur  Fri   Sat"
    
    
    
    int get_days(int, int, int);   //返回从公元元年算起,某年某月某日是第几天, 用这个数字算星期几 
    int days_of_year(int, int, int);  //返回某年某月某日是当前年份第几天
    int days_of_month(int, int);  //返还某年某月有几天
    int day_of_week(int, int, int); //返回某年某月某日是星期几,星期天返回0 
    _Bool is_leap_year(int);    //返回当前年份是否为闰年
    void print_date_of_month(int, int);    // 打印某年某月的日历     
    
    int main()
    {
        int days = get_days(2018, 5, 9) % DAYS_PER_WEEK;
        printf("%d
    ", day_of_week(2018, 5, 9));
        
        print_date_of_month(2018, 8);
        
        return 0;
     }
    
    
    
    //返回这一天从公元元年算起是第几天
     
    int get_days(int year, int month, int day)
    {
        int days = days_of_year(year, month, day);
        int temp = year-1;
        return temp * 365 + temp / 4 - temp / 100 + temp / 400 +  days;
    }
     
     
    
     //返回这一天在当年是第几天 
    int days_of_year(int year, int month, int day)
    {
         int i;
         int days = 0;
         for(i = 1; i < month; i++)
         {
             days += days_of_month(year, i);
             
         }
         return days + day;
    }
    
    //返回这个月一共有多少天 
    int days_of_month(int year, int month)
    {
        //存储平年每月的天数 
        const int  month_days[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        if(2 == month && is_leap_year(year))
            return 29; // 如果是闰年2月,返回29天 
        else
            return month_days[month-1];  //正常返回 
    }
    
    //判断是不是闰年 
    _Bool is_leap_year(int year)
    {
        return (year % 400 == 0 ) || (year % 4 == 0 && year % 100 != 0);
    }
    
    int day_of_week(int year, int month, int day)
    {
        return get_days(year, month, day) % DAYS_PER_WEEK;
     } 
    
    //输出某年某个月的日历 
    void print_date_of_month(int year, int month)
    {
        //打印月份,为了让月份显示居中, 打印一些空格(根据打印星期的那行大概估算一下) 
        printf("               ");
        switch(month)
        {
            case 1: printf("January
    ");    break;
            case 2: printf("February
    ");    break;
            case 3: printf("March
    ");    break;
            case 4: printf("April
    ");    break;
            case 5: printf("May
    ");    break;
            case 6: printf("June
    ");    break;
            case 7: printf("July
    ");    break;
            case 8: printf("August
    ");    break;
            case 9: printf("September
    ");    break;
            case 10: printf("October
    ");    break;
            case 11: printf("November
    ");    break;
            case 12: printf("December
    ");    break;
            default: printf("Bad input of month, please enter a right month.
    "); return;
            
        }
        //先把星期打印出来 
        printf("%s
    ", DATE_HEADER);
        
        //先求出这个月第一天星期几 
        int day_of_week = get_days(year, month, 1) % DAYS_PER_WEEK;
        
        //因为星期天是在第一个位置,所以对星期求模(求余),比如星期天,其实是第一个位置,所以它应该是 7 % 7 = 0; 
        int first = day_of_week % DAYS_PER_WEEK;
        
        //求出这个月一共有几天 
        int days = days_of_month(year, month);
        
        int i, j;
        //先打印第一天的位置 
        for(i = 0; i < first; i++) {
            printf("      ");
        }
        printf("%6d", 1);
        //如果今天是星期六,换行 
        if(first == 6)
            printf("
    ");
        
        //打印剩下的日期 
        for(i = 1; i < days; i++)
        {
            printf("%6d", i + 1);
            //如果是星期六或者是最后一天,换行 
            if((first + i) % 7 == 6 || i + 1 == days)
                printf("
    ");
        } 
    }

    跑起来测试结果, 打印的日历是2018年8月的

     

  • 相关阅读:
    Linux内核tracepoints
    Linux 设备驱动的固件加载
    Android HIDL HAL 接口定义语言详解
    Android HIDL 详解
    Android各版本对应的SDK版本
    ifconfig调用过程
    Input系统—启动篇
    Linux下2号进程的kthreadd--Linux进程的管理与调度
    rest_init函数分析(续)
    【python】-常用模块2
  • 原文地址:https://www.cnblogs.com/yeyeck/p/9536143.html
Copyright © 2011-2022 走看看