zoukankan      html  css  js  c++  java
  • C++ 实现万年历(原创)

    任务要求

    功能要求:

    1)提供菜单方式选择,假定输入的年份在1940-2040年之间。

    2)输入一个年份,输出是在屏幕上显示该年的日历。

    3)输入年月,输出该月的日历,如图2-1所示:

      

                              2- 1 月日历

    4)输入年份、月份、日期,计算得到的是这一天据今天有多少天,星期几。

    5)输入公历的年月日,输出农历年月日。

    6)输入农历节气,输出当年农历的年月日及公历年月日。可以假定只涉及年份是1940年到2040年。

    总体设计

    将文件三部分 Date.h、main.cpp、Date.cpp

    1) Date.h:包括函数的声明。

    2) main.cpp:包含调用与模拟交互界面的函数代码

    3) Date.cpp:

    //输入输入一个年份,输出是在屏幕上显示该年的日历。

    void print_annual_calendar(int year)

    //输入年月,输出该月的日历。

    void print_monthly_calendar(int year,int month)

    //输入年份、月份、日期,计算得到的是这一天据今天有多少天,星期几。

    void print_number_week(int year,int month ,int day)

    //输入公历,显示农历。

    void gregorian_to_lunar (int year,int month,int day)

    //输入农历节气,输出当年农历的年月日和公历年月日。

    void solar_term(char *str)

    详细设计说明

    (1) 查询距今多少天,星期几?

    ①计算某一日期到1939年1月1日的天数:getDaysTo1939(int year, int month, int day)

    1. 判断是否是闰年(平年365天,闰年366天),函数如表4-1所示:

    4- 1 isLeapYear函数

    定义函数

    bool isLeapYear(int year)

    返回值

    若year年是闰年返回true,否则返回false

    参数说明

    year参数是要判断的年份

    1. 判断某年某月有多少天?函数如表4-2所示:

    4- 2 getDaysOfMonth函数

    定义函数

    int getDaysOfMonth(int year,int month)

    返回值

    返回year年month月的天数

    参数说明

    year、month参数分别是要查询的年、月

     例如:计算2020年8月14日到1939年1月1日的天数。首先1939-2019年是整数年,直接判断是否是闰年,然后增加天数。2020年不是整年,但1-7月是整数月,根据年、月获取当月天数累加。最后再加天数day,便得出相距与1939年1月1日的天数。

    ②计算查询日期距今天多少天?getDaysOfMonthToToday(int year, int month, int day) ,函数如表4-3所示:

    1. 通过函数获取系统时间,通过getDaysTo1939(),获取系统时间距1939年1月1日的天数num1。
    2. 使用键盘输入的日期,通过getDaysTo1939(),获取输入日期距1939年1月1日的天数num2。
    3. 使用num1-num2计算输入日期距今天的天数,正数为已过去时间,负数为未来时间。

    4- 3 getDaysOfMonthToToday函数

    定义函数

    int getDaysOfMonthToToday(int year,int month,int day)

    返回值

    返回距今天数,正值为过去,负值为未来

    参数说明

    year、month、day 分别为要查询的年、月、日

    ③计算输入日期是星期几:getDayOfWeek(int year,int month,int day) ,函数如表4-4所示:

     

    1. 知道1939年1月1日是星期日,然后计算查询日期与1939年距离多少天,然后利用(天数%7)获取余数,得出星期属性。

    4- 4 getDayOfWeek函数

    定义函数

    String getDayOfWeek(int year,int month,int day)

    返回值

    返回字符串星期数

    参数说明

    year、month、day 分别为要查询的年、月、日

    (2) 打印月日历

    1. 获取当月1日是星期几,通过getDayOfWeek1()获取当月一号是星期几,然后通过打印空格使得当月1日,停在所对应的星期下方,函数如表4-5所示:

    4- 5 getDayOfWeek1函数

    定义函数

    int getDayOfWeek1(int year,int month,int day)

    返回值

    返回星期数,0代表星期天

    参数说明

    year、month、day 分别为要查询的年、月、日

    1. 获取当月天数,通过getDaysOfMonth()获取,打印完最后一天时间便结束,函数如表4-6所示:

    4- 6 getDaysOfMonth函数

    定义函数

    int getDaysOfMonth(int year,int month)

    返回值

    返回year年month月天数

    参数说明

    year、month分别为要查询的年、月

    (3) 打印年日历

    ① 打印季度日历,函数如表4-7所示:

    1. 首先打印日历头信息三遍(由于是按照季度输出,一行包含三个月),格式:(月份 SUN MON SUN MON TUE WED THU FRI SAT)
    2. 依次打印日历的第一行,每月的第一日对应的星期数,通过打印空格来调整。
    3. 依次打印连续的日期。最后一行,日期与日期之间依然要使用空格来调整位置。

    4- 7 print_seasons_calendar函数

    定义函数

    void print_seasons_calendar(int year,int num)

    返回值

    无返回值

    参数说明

    year、num分别为要打印的年、季度,num可取1,2,3,4

    ① 打印年日历,函数如表4-8所示:

    1. 通过for循环打印四个季度的日历,便完成年日历的输出。

    4- 8 print_annual_calendar函数

    定义函数

    void print_annual_calendar(int year)

    返回值

    无返回值

    参数说明

    year为要打印的年份

    (4) 公历转农历

    ① 计算输入的时间距离1939年1月1日的天数。

    ② 获取农历年天数(通过农历数据表查询):getDayOfNongYear(int year)

    1. 获取农历年是否为闰年,返回闰月月份,函数如表4-9所示:

    4- 9 isNongLeapYear函数

    定义函数

    int isNongLeapYear(int year)

    返回值

    返回农历year年闰月月份,0表示不闰

    参数说明

    year为要查询的年

    1. 获取每个月有多少天,函数如表4-10所示:

    4- 10 getDaysOfMonthOfNongMonth函数

    定义函数

    int getDaysOfMonthOfNongMonth(int year,int month)

    返回值

    返回农历year年month月的天数

    参数说明

    year、month分别为要查询的年、月

    1. 获取闰月大小,函数如表4-11所示: 

    4- 11 is_large_month函数

    定义函数

    bool is_large_month(int year)

    返回值

    闰大月返回true,闰小月返回false

    参数说明

    year为要查询的年

    ③ 计算农历日期,函数如表4-12所示:

    1. 由于1939年1月1日农历往往是1938年,所以首先减去公历1939年1月1日到农历1939年正月初一的天数。
    2. 循环计算便得出农历日期。日期的文字形式可以保存在数组中进行拼接输出。

    4- 12 gregorian_to_lunar函数

    定义函数

    void gregorian_to_lunar (int year,int month,int day)

    返回值

    无返回值

    参数说明

    year、month、day分别为要转换的年、月、日

    (5) 查询节气时间,函数如表4-13所示:

    1. 计算二十四节气对应的公历日期(通过寿星公式计算)
    2. 得出公历日期,直接使用公历转农历函数,打印农历日期。

    4- 13 solar_term函数

    定义函数

    void solar_term(int year,char* str)

    返回值

    无返回值

    参数说明

    year代表要查询的年份,str表示查询的节气名称,如立秋。

    调试与测试

    (1) 交互界面显示

     

    (2) 打印年日历

     

                          图3- 2 年日历

    (3) 打印月日历

                3- 3  月日历

    (4) 查询距今多少天,星期几? 

                       3- 4  距今天数,星期数

    (5) 公历转农历

                        3- 5  公历转农历

     (6) 查询节气时间

                    图3- 6  查询二十四节气

    代码实现

    Date.h:
    #ifndef DATE_H
    #define DATE_H
    /*输入年份、月份、日期,计算得到的是这一天据今天有多少天?星期几?*/
    void print_number_week(int year,int month,int day);
    /*输入年月,输出该月的日历。*/
    void print_monthly_calendar(int year,int month);
    /*输入输入一个年份,输出是在屏幕上显示该年的日历。*/
    void print_annual_calendar(int year);
    /*输入公历,显示农历。*/
    void gregorian_to_lunar (int year,int month,int day);
    /*输入年份,二十四节气*/
    void solar_term(int year,char* str);
    /*欢迎界面*/
    void print();
    #endif // DATE_H
    
    main.cpp:
    #include <iostream>
    #include "Date.h"
    using namespace std;
    
    int main()
    {
    
        int num;
        char solar_Terms[3];
        int year,month,day;
        print();
        while(1)
        {
    
            cout<<"
    请选择服务序号:";
            cin>>num;
            switch(num)
            {
            case 1:
                cout<<"请输入要查询的年份:";
                cin>>year;
                print_annual_calendar(year);
                break;
            case 2:
                cout<<"请输入要查询的年、月:";
                cin>>year>>month;
                print_monthly_calendar(year,month);
                break;
            case 3:
                cout<<"请输入要查询的年、月、日:";
                cin>>year>>month>>day;
                print_number_week(year,month,day);
                break;
            case 4:
                cout<<"请输入要查询的年、月、日:";
                cin>>year>>month>>day;
                gregorian_to_lunar (year,month,day);
                break;
            case 5:
                cout<<"请输入要查询的年份及节气:";
                cin>>year>>solar_Terms;
                solar_term(year,solar_Terms);
                break;
            case 0:
                return 0;
            }
        }
        return 0;
    }
    
    Date.cpp:
    #include "Date.h"
    #include <stdio.h>
    #include <ctime>
    #include <string>
    #include <iostream>
    #include <iomanip>
    #include <cmath>
    #include <string.h>
    
    using namespace std;
    
    
    /*农历查询表  来源:https://www.jianshu.com/p/57e7bd43c00b    */
    /*第1位    表示假如有闰月,0代表闰小月,1代表闰大月
     *第2-4位  表示12个二进制位 一位表示一个月是大月还是小月
     *最后1位  表示闰哪个月,0表示不闰*/
    unsigned int LunarCalendar[199] =
    {
        /*1900年开始*/
        /*0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,
        0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,
        0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,
        0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,*/
        /*我的日历要求1940-2040年 以上用不到*/
    
        0x0c950,/*1939年*/   /*查询公历1940年1月,农历其实是1939年*/
        0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,
        0x06ca0,0x0b550,0x15355,0x04da0,0x0a5d0,0x14573,0x052d0,0x0a9a8,0x0e950,0x06aa0,
        0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,
        0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b5a0,0x195a6,
        0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,
        0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,
        0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,
        0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,
        0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,
        0x05aa0,0x076a3,0x096d0,0x04bd7,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,
        0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0
    };
    
    /*获取系统时间*/
    void gettime(int &year,int &month,int &day)
    {
        time_t time1;
        struct tm *ptime;
        time(&time1);
        ptime = localtime(&time1);
        year=ptime->tm_year + 1900;
        month=ptime->tm_mon + 1;
        day=ptime->tm_mday;
    }
    
    /*判断year年是否是闰年*/
    bool isLeapYear(int year)
    {
        /*可以被4且100整除或者可以被400整除*/
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    /*获取year年month月有多少天*/
    int getDaysOfMonth(int year,int month)
    {
        /*平年各月公历天数*/
        int days[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
        if(isLeapYear(year)&&month==2)
            return 29;
        else
            return days[month-1];
    }
    
    /*获取year年month月day日到1939年1月1日的天数*/
    int getDayTo1939(int year,int month,int day)
    {
        int days=0;
        /*从1939年开始计算,直到year-1年,它们都是整数年*/
        for(int i=year-1; i>=1939; i--)
        {
            if(isLeapYear(i))
                days+=366;
            else
                days+=365;
        }
        /*计算year年1月到year年month-1月  它们是整数月*/
        for(int i=month-1; i>0; i--)
        {
            days+=getDaysOfMonth(year,i);
        }
        /*计算year年month月1日到yera年month月day日天数*/
        days+=day;
        return days-1;
    }
    
    /*获取year年month月day日是星期几*/
    string getDayOfWeek(int year,int month,int day)
    {
        string weeks[7]= {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
        /*获取year年month月day日到1939年1月1日的天数*/
        int days=getDayTo1939(year,month,day);
        int week=days%7;
        return weeks[week];
    }
    /*整型版星期几*/
    int getDayOfWeek1(int year,int month,int day)
    {
        int days=getDayTo1939(year,month,day);
        int week=days-(days/7)*7;
        return week;
    }
    
    /*获取year年month月day日到现在的天数 正值为过去,负值为未来*/
    int getDaysOfMonthToToday(int year,int month,int day)
    {
        int nowyear;
        int nowmonth;
        int nowday;
        gettime(nowyear,nowmonth,nowday);
        /*现在时间到1939年1月1日的天数*/
        int nowto1939=getDayTo1939(nowyear,nowmonth,nowday);
        /*输入的时间到1939年1月1日的天数*/
        int tempto1939=getDayTo1939(year,month,day);
        /*正数为过去,负数为未来*/
        return nowto1939-tempto1939;
    }
    
    /*检查年月日合法性*/
    bool checkDate(int year,int month,int day)
    {
        /*还需要判断 year年month月  是否含day天,比如4月有30天,输入31就是错误的*/
        if(year<1939||year>2041||month<0||month>12||day<0||day>getDaysOfMonth(year,month))
            return false;
        else
            return true;
    }
    
    
    void print_number_week(int year,int month,int day)
    {
        if(!checkDate(year,month,day))
        {
            cout<<"日期输入出错,请确保日期正确性!"<<endl;
            return;
        }
        if(getDaysOfMonthToToday(year,month,day)>0)
            cout<<year<<""<<month<<""<<day<<""<<getDayOfWeek(year,month,day)<<"	距现在已过去"<<getDaysOfMonthToToday(year,month,day)<<""<<endl;
        else
            cout<<year<<""<<month<<""<<day<<""<<getDayOfWeek(year,month,day)<<"	距现在还有"<<-getDaysOfMonthToToday(year,month,day)<<""<<endl;
    }
    
    /*输入年份月份输出月日历表*/
    void print_monthly_calendar(int year,int month)
    {
        if(year>2041||year<1939||month>12||month<1)
        {
            cout<<"日期输入出错,请确保日期正确性!"<<endl;
            return;
        }
        cout<<"	"<<year<<""<<month<<""<<endl;
        cout<<" SUN MON TUE WED THU FRI SAT"<<endl;
        /*计算year年month月1日星期几*/
        int week=getDayOfWeek1(year,month,1);
        /*调整1日到对应的星期数*/
        for(int i=1; i<=week&&week!=7; i++)
            cout<<"    ";
        /*打印日历信息*/
        for(int i=1; i<=getDaysOfMonth(year,month); i++)
        {
            cout<<setw(3)<<i<<" ";
            if((week+i)%7==0)
                cout<<endl;
        }
    }
    
    
    /*输入年份、季度 一行输出3个月*/
    void print_seasons_calendar(int year,int num)
    {
        if(num>4||num<0)
        {
            cout<<"输入季度出错!"<<endl;
            return;
        }
        int month=1+3*(num-1);
        /*打印日历头*/
        cout<<month<<" SUN MON TUE WED THU FRI SAT	"<<month+1<<" SUN MON TUE WED THU FRI SAT	"<<month+2<<" SUN MON TUE WED THU FRI SAT"<<endl;
        /*week1、week2、week3 分别代表一个季度的三个月的一日对应星期数*/
        int week1=getDayOfWeek1(year,month,1);
        int week2=getDayOfWeek1(year,month+1,1);
        int week3=getDayOfWeek1(year,month+2,1);
        /*tmp1、tmp2、tmp3分别代表三个月的最大天数*/
        int tmp1=getDaysOfMonth(year,month),tmp2=getDaysOfMonth(year,month+1),tmp3=getDaysOfMonth(year,month+2);
    
        int day1,day2,day3;
    
        /*依次输出第一行信息*/
        cout<<"  ";
        for(int i=1; i<=week1 &&week1!=7; i++)
            cout<<"    ";
        for(int i=1; i<=tmp1; i++)
        {
            cout<<setw(3)<<i<<" ";
            if((week1+i)%7==0)
            {
                day1=i+1;
                break;
            }
        }
        cout<<"    ";
        for(int i=1; i<=week2 && week2!=7; i++)
            cout<<"    ";
        for(int i=1; i<=tmp2; i++)
        {
            cout<<setw(3)<<i<<" ";
            if((week2+i)%7==0)
            {
                day2=i+1;
                break;
            }
        }
        cout<<"    ";
        for(int i=1; i<=week3 && week3!=7; i++)
            cout<<"    ";
        for(int i=1; i<=tmp3; i++)
        {
            cout<<setw(3)<<i<<" ";
            if((week3+i)%7==0)
            {
                day3=i+1;
                cout<<endl;
                break;
            }
        }
    
        /*打印余下信息*/
        for(int j=0; j<5; j++)
        {
            /*如果三个月信息全部打印完,则退出*/
            if(day1>tmp1&&day2>tmp2&&day3>tmp3)
                break;
            /*数字21代表一行三个周,可容纳21天*/
            for(int i=0; i<21;)
            {
                cout<<"  ";
                while(i<7)
                {
                    i++;
                    /*如果没打印完就打印数字,如果整月天数已经打印完,则输出空格*/
                    if(day1<=tmp1)
                        cout<<setw(3)<<day1++<<" ";
                    else
                        cout<<setw(3)<<" "<<" ";
                }
                /*打印月份与月份之间的间隔*/
                cout<<"    ";
                while(i<14&&i>=7)
                {
                    i++;
                    if(day2<=tmp2)
                        cout<<setw(3)<<day2++<<" ";
                    else
                        cout<<setw(3)<<" "<<" ";
                }
                cout<<"    ";
                while(i<21&&i>=14)
                {
                    i++;
                    if(day3<=tmp3)
                        cout<<setw(3)<<day3++<<" ";
                    else
                        cout<<setw(3)<<" "<<" ";
                }
            }
            cout<<endl;
        }
        cout<<endl;
    }
    
    /*显示欢迎界面*/
    void print()
    {
        cout<<"
    		欢迎来到我的日历表(1940-2040年)"<<endl;
        cout<<"		功能选择:"<<endl;
        cout<<"		1.查询年日历表"<<endl;
        cout<<"		2.查询月日历表"<<endl;
        cout<<"		3.查询距今多少天?星期几?"<<endl;
        cout<<"		4.输入公历查询农历"<<endl;
        cout<<"		5.输入节气查询对应公历、农历"<<endl;
        cout<<"		*****按0退出*****"<<endl;
    }
    
    /*输出年日历表*/
    void print_annual_calendar(int year)
    {
        if(year>2041||year<1939)
        {
            cout<<"日期输入出错,请确保日期正确性!"<<endl;
            return;
        }
        cout<<"					  "<<"------------"<<endl;
        cout<<"					  "<<year<<"年日历表"<<endl;
        cout<<"					  "<<"------------"<<endl;
    
        /*循环输出四个季度 打印完整年日历*/
        for(int i=1; i<=4; i++)
        {
            print_seasons_calendar(year,i);
        }
    }
    
    
    string nongMonth[]= {" ","正月","二月","三月","四月","五月","六月","七月","八月","九月","十月","冬月","腊月"};
    string nongday[]= {"","","","","","","","","","",""};
    string nongday2[]= {"","","廿",""};
    
    
    /*判断润大小月*/
    bool is_large_month(int year)
    {
        /*查表找出是否为闰月 判断high是不是为0*/
        int high =(LunarCalendar[year-1939]>>16);
        if(high==0x00)
            return false;
        else
            return true;
    }
    /*返回 润几月  0代表不闰*/
    int isNongLeapYear(int year)
    {
        /*输出农历润几月*/
        int low = LunarCalendar[year-1939] & 0xF;
        return low;
    }
    
    /*判断农历某年某月多少天*/      /*LunarCalendar 表示农历对照表*/
    int getDaysOfMonthOfNongMonth(int year,int month)
    {
        /*查表,根据大小月,计算农历月天数*/
        int bit=1 << (16-month);
        if((LunarCalendar[year-1939]/*&0x0000FFFF*/&bit)==0)
            return 29;
        else
            return 30;
    }
    
    /*判断某年农历多少天*/
    int getDayOfNongYear(int year)
    {
        int days=0;
        /*农历十二个月天数*/
        for(int i=1; i<=12; i++)
        {
            days+=getDaysOfMonthOfNongMonth(year,i);
        }
        /*假如有闰月,加上闰月天数*/
        if(isNongLeapYear(year)!=0)
        {
            if(is_large_month(year))
                days+=30;
            else
                days+=29;
        }
        return days;
    }
    
    
    /*输出农历日历*/
    void printNong(int days)
    {
        int year=1939,month=1,day=1;
        /*由于1939年1月1日往往是农历1938年,所以减去48天,从1939年正月初一计算,因为本计算器计算范围为1940年-2040年 所以可以满足*/
        days-=48;
    
        /*判断减去下一年的天数,会不会是负值,不是便减去并增加农历年*/
        for(int i=1939; (days-getDayOfNongYear(i))>0; i++)
        {
            days-=getDayOfNongYear(i);
            year=i+1;
        }
        int num;
        int signal=0;
        /*判断减去下一月天数,会不会是负值,不会便农历月加1*/
        for(int j=1; ((days-getDaysOfMonthOfNongMonth(year,j))>0)&&j<12; j++)
        {
            days-=getDaysOfMonthOfNongMonth(year,j);
            if(j==isNongLeapYear(year))
            {
                if(is_large_month(year))
                {
                    days-=30;
                    num=30;
                }
                else
                {
                    days-=29;
                    num=29;
                }
            }
            /*当减去农历月的时候,加入变为负值,那么再加回来*/
            if(days<0)
            {
                /*农历闰月标记*/
                signal=1;
                days +=num;
                month=j;
                break;
            }
            month=month+1;
        }
        /*剩余天数便是农历日*/
        day=days;
        cout<<year<<"";
        if(signal==1)
            cout<<"";
        cout<<nongMonth[month];
        if(day>0&&day<=10)
        {
            cout<<""<<nongday[day];
        }
        else if(day>10&&day<20)
        {
            cout<<""<<nongday[day%10];
        }
        else if(day==20)
        {
            cout<<"二十";
        }
        else if(day>20 && day<30)
        {
            cout<<"廿"<<nongday[day%10];
        }
        else if(day==30)
        {
            cout<<"三十";
        }
        cout<<endl;
    }
    
    /*打印农历*/
    void gregorian_to_lunar (int year,int month,int day)
    {
        if(!checkDate(year,month,day))
        {
            cout<<"日期输入出错,请确保日期正确性!"<<endl;
            return;
        }
        cout<<"公历:"<<year<<""<<month<<""<<day<<""<<"   "<<"农历:";
        int days=getDayTo1939(year,month,day);
        /*根据天数打印农历*/
        printNong(days);
    }
    
    /*通式寿星公式 计算二十四节气  公式来源:https://www.jianshu.com/p/1f814c6bb475*/
    /*20,21世纪C值*/
    float C_value_21[]= {3.87,18.73,5.63,20.646,4.81,20.1,5.52,21.04,5.678,21.37,7.108,22.83,7.5,23.13,7.646,23.042,8.318,23.438,7.438,22.36,7.18,21.94,5.4055,20.12};
    float C_value_20[]= {4.6295,19.4599,6.3826,21.4155,5.59,20.888,6.318,21.86,6.5,22.2,7.928,23.65,28.35,23.95,8.44,23.822,9.098,24.218,8.218,23.08,7.9,22.6,6.11,20.84};
    /*节气基础月*/
    float C_month[]= {2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
    void solar_term(int year1,char* str)
    {
        int year,month,day;
        year=year1;
        int tmp=-1;//表示节气顺序
        const char* temp[24]= {"立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至","小寒","大寒"};
        /*比较字符并赋值tmp 如:0就代表立春*/
        for(int i=0; i<24; i++)
        {
            if(strcmp(str,temp[i])==0)
            {
                tmp=i;
                break;
            }
        }
        if(tmp==-1)
        {
            cout<<"节气拼写出错!"<<endl;
            return;
        }
    
        if(tmp==0||tmp==1||tmp==22||tmp==23)
        {
            if(year>=2000)
            {
                month=C_month[tmp];
                day=floor((year%100)*0.2422+C_value_21[tmp])-floor((year%100-1)/4);
            }
            else
            {
                month=C_month[tmp];
                day=floor((year%100)*0.2422+C_value_20[tmp])-floor((year%100-1)/4);
            }
        }
        else
        {
            if(year>=2000)
            {
                month=C_month[tmp];
                day=floor((year%100)*0.2422+C_value_21[tmp])-floor((year%100)/4);
            }
            else
            {
                month=C_month[tmp];
                day=floor((year%100)*0.2422+C_value_20[tmp])-floor((year%100)/4);
            }
        }
    
    //特殊情况
        if((year==2026 && tmp==1)||(year==1918 && tmp==21)||(year==2021 && tmp==21)||(year==2019 && tmp==22))
        {
            day--;
        }
        if((year==2084 && tmp==3)||(year==1911 && tmp==6)||(year==2008 && tmp==7)||(year==1902 && tmp==8)||(year==1928 && tmp==9)||(year==1925 && tmp==10)||(year==2016 && tmp==10)||(year==1922&& tmp==11)||(year==2002&&tmp==12)||(year==1927&&tmp==14)||(year==1942&&tmp==15)||(year==2089 && tmp==17)||(year==2089&&tmp==18)||(year==1978&&tmp==19)||(year==2054 && tmp==20)||(year==1982&&tmp==22)||(year==2000 && tmp==23)||(year==2082&&tmp==23))
        {
            day++;
        }
        if(C_month[tmp]>12)
        {
            month=1;
        }
        cout<<temp[tmp]<<": ";
        /*根据公式计算的年月日,将其转换为农历*/
        gregorian_to_lunar (year,month,day);
    }
  • 相关阅读:
    python3+requests库框架设计03-请求重新封装
    python3+requests库框架设计02-封装日志类
    [patl2-001]紧急救援
    [patl1-046]整除光棍
    latex学习
    matlab基础功能实践
    dll注入及卸载实践
    编译原理大作业暂存
    12.24逆向工程上机作业整理
    [poj1703]Find them, Catch them(种类并查集)
  • 原文地址:https://www.cnblogs.com/handsometaoa/p/13588549.html
Copyright © 2011-2022 走看看