#include<iostream>
#include<fstream>
#include<iomanip>
#include <Windows.h>
#include "SolarCalendar.h"
#include "ConsoleColor.h"
#include "LunarCalendar.h"
using namespace std;
int everyMonth[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
void PermanentCalendar::Input()
{
int choose;
bool flag=true;
while(flag)
{
cout<<endl;
cout<<white<<"欢迎使用万年历,请选择:"<<endl;
cout<<endl;
cout<<white<<" 1:输入年份,显示该年的年历"<<endl;
cout<<white<<" 2:输入年月,显示该月的日历"<<endl;
cout<<white<<" 3:输入日期,显示该日星期及农历"<<endl;
cout<<white<<" 4:退出"<<endl;
cout<<endl;
cout<<white<<"输入您的选择: ";
while(1)
{
if(cin>>choose && cin.get()=='\n')
break;
else
{
cout<<red<<"请不要输入字符型,重新输入:"<<endl;
cin.clear();
while(cin.get()!='\n')
;
}
}
switch(choose)
{
case 1:SetYear();break;
case 2:SetMonth();break;
case 3:SetDays();break;
case 4:flag=false;break;
default:
{
system("cls");
cout<<red<<"输入错误,请重新输入"<<endl;
}
}
}
}
bool PermanentCalendar::IsRight(int year,int month,int day) //判断日期输入是否正确
{
if(year<1 || year>9999 || month<1 || month>12)//年月是否正确
return false;
//日期是否正确
if(day<0)
return false;
else if( day==29)
return((month==2 && IsLeap(year))|| month!=2);
else if(day==31)
return(month==1 ||month==3 ||month==5 ||month==7 ||month==8 || month==10 || month==12);
else if(day>31)
return false;
else
return true;
}
void PermanentCalendar::SetDays()
{
int weekDay;
int solar_year=0;
char solar_month=0;
char solar_day=0;
cout<<white<<"请输入年 月 日:"<<endl;
while(1)
{
if(cin>>year>>month>>day && cin.get()=='\n')
break;
else
{
cout<<red<<"输入错误,请重新输入:"<<endl;
cin.clear();
while(cin.get()!='\n')
;
}
}
while(!IsRight(year,month,day))
{
cout<<red<<"输入错误,请重新输入年 月 日:"<<endl;
cin>>year>>month>>day;
}
weekDay=GetDays(year, month,day)%7;
system("cls");
cout<<yellow<<"阳历:";
switch(weekDay)
{
case 0: cout<<year<<"年"<<month<<"月"<<day<<"日 星期日"<<endl; break;
case 1: cout<<year<<"年"<<month<<"月"<<day<<"日 星期一"<<endl; break;
case 2: cout<<year<<"年"<<month<<"月"<<day<<"日 星期二"<<endl; break;
case 3: cout<<year<<"年"<<month<<"月"<<day<<"日 星期三"<<endl; break;
case 4: cout<<year<<"年"<<month<<"月"<<day<<"日 星期四"<<endl; break;
case 5: cout<<year<<"年"<<month<<"月"<<day<<"日 星期五"<<endl; break;
case 6: cout<<year<<"年"<<month<<"月"<<day<<"日 星期六"<<endl; break;
}
cout<<endl;
solar_lunar(year,month,day);
if(lunar_day<10)
cout<<"农历:"<<lunar_year<<"年"<<lunar_month<<"月"<<"初"<<lunar_day<<endl;
else
cout<<"农历:"<<lunar_year<<"年"<<lunar_month<<"月"<<lunar_day<<endl;
}
bool PermanentCalendar::IsLeap(int year)//判断是否是闰年
{
return ((year%4==0 && year!=0 && year%100!=0)||(year%400==0));
}
int PermanentCalendar::GetDays(int year,int month,int day)//得到此日前所有已经过的日子
{
int yearDays, monthDays=0,sum;
int accumulate=0;
for(int i=1;i<year;i++)
if(IsLeap(i))
accumulate++;
yearDays=accumulate+365*(year-1);
if(IsLeap(year))
everyMonth[2]=29;//如果是闰年,则2月为29天
for(int j=1;j<month;j++)
monthDays+=everyMonth[j];
sum=yearDays+monthDays+day;//所有已经过的日子之和
return sum;
}
void PermanentCalendar::SetMonth()//当输入的是年月时,处理
{
int weekDay;
day=1;
cout<<white<<"请输入年 月:"<<endl;
while(1)
{
if(cin>>year>>month && cin.get()=='\n')
break;
else
{
cout<<red<<"输入错误,请重新输入:"<<endl;
cin.clear();
while(cin.get()!='\n')
;
}
}
while(!IsRight(year,month,day))//判断输入是否正确
{
cout<<red<<"输入错误,请重新输入年 月:"<<endl;
cin>>year>>month;
}
system("cls");
weekDay=GetDays(year, month,day)%7;
Print(year,month);
}
void PermanentCalendar::SetYear()
{
month=1,day=1;
cout<<white<<"请输入年:";
while(1)
{
if(cin>>year && cin.get()=='\n')
break;
else
{
cout<<red<<"输入错误,请重新输入:"<<endl;
cin.clear();
while(cin.get()!='\n')
;
}
}
while(!IsRight(year,month,day))//判断是否输入正确,若错误,请重新输入
{
cout<<red<<"输入错误,请重新输入年:"<<endl;
cin>>year;
}
system("cls");
cout<<endl;
cout<<blue<<" 万年历打印在Calendar文档中,请查看。"<<endl;
Output(year);
for(int k=1;k<=12;k++)//将12个月的万年历在界面上输出
Print(year,k);
}
void PermanentCalendar:: Print(int year,int month)//打印到界面上
{
int weekday;
day=1;
cout<<yellow<<" 公元"<<year<<"年"<<month<<"月"<<endl;
cout<<endl;
cout<<" SUN MON TUE WES THU FRI SAT"<<endl;
weekday=GetDays(year, month,day)%7;//所有的日期之和取余
switch(weekday)//输出处理
{
case 0: cout<<" "<<setw(6)<<setiosflags(ios::left)<<"1"; break;
case 1: cout<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 2: cout<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 3: cout<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 4: cout<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 5: cout<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 6: cout<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
}
for(int i=2;i<=everyMonth[month];i++)
{
weekday=(++weekday)%7;
if(!weekday)
{
cout<<endl;
cout<<" "<<setw(6)<<setiosflags(ios::left)<<i;
}
else
cout<<setw(6)<<setiosflags(ios::left)<<i;
}
cout<<endl;
cout<<endl;
//SetColor(40,0);
}
void PermanentCalendar::Output(int year)//打印到文本框内
{
int weekday;
int i,j;
month=1;
day=1;
ofstream outfile("Calendar.txt",ios::out);
for(i=1;i<=12;i++)
{
outfile<<" 公元"<<year<<"年"<<i<<"月"<<endl;
outfile<<" SUN MON TUE WES THU FRI SAT"<<endl;
weekday=GetDays(year, i,day)%7;
switch(weekday)
{
case 0: outfile<<" "<<setw(6)<<setiosflags(ios::left)<<"1"; break;
case 1: outfile<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 2: outfile<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 3: outfile<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 4: outfile<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 5: outfile<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
case 6: outfile<<" "<<setw(6)<<setiosflags(ios::left)<<"1";break;
}
for( j=2;j<=everyMonth[i];j++)
{
weekday=(++weekday)%7;
if(!weekday)
{
outfile<<endl; outfile<<" "<<setw(6)<<setiosflags(ios::left)<<j;
}
else
outfile<<setw(6)<<setiosflags(ios::left)<<j;
}
outfile<<endl;
outfile<<endl;
}
cout<<endl;
outfile.close();
}
int main()
{
PermanentCalendar pc;
pc.Input();
return 0;
}
#ifndef __SOLARCALENDAR__
#define __SOLARCALENDAR__
class PermanentCalendar
{
public:
void Input();
void SetMonth();
void SetDays();
void SetYear();
bool IsLeap(int year);
bool IsRight(int year,int month,int day);
int GetDays(int year,int month,int day);
void Print(int year,int month);
void Output(int year);
private:
int year;
int month;
int day;
};
#endif
#ifndef __LUNARCALENDAAR__
#define __LUNARCALENDAAR__
#include <stdio.h>
#include <conio.h>
int year=0,lunar_year=0;
int month=0,lunar_month=0;
int day=0,lunar_day=0;
/*1900-2050年的农历数据
数据格式说明
5位十六进制数字 例:04bd8
1 位: 1表示闰月30天,0表示29天
2、3、4位: 转换二进制为:0100 1011 1101(1为30天,0为29天)
04bd8表示为(13个月):29,30,29,29,30,29,30,30,30(闰8月),30,30,29,30;
5 位: 如果有闰月,则为月份,没有则为0*/
long int lunar_info[]=
{
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,0x0c950,
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,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,
0x14b63
};
int get_leap_month(int lunar_year)
{
return lunar_info[lunar_year-1900]&0xf;
}
int get_leap_month_day( int lunar_year)
{
if(get_leap_month(lunar_year))
return( ( (lunar_info[lunar_year-1900]) & 0x10000 ) ? 30:29 );
else
return(0);
}
int get_lunar_month_total( int lunar_year, int lunar_month)
{
return( (lunar_info[lunar_year-1900] & (0x10000>>lunar_month) ) ? 30:29 );
}
int get_lunar_year_total( int lunar_year)
{
int sum=348;
int i;
for(i=0x8000;i>0x8; i>>=1)
sum+=(lunar_info[lunar_year-1900]&i)?1:0;
return(sum+get_leap_month_day(lunar_year));
}
int leap( int year)
{
if( (year%4==0 &&year%100!=0) || year%400==0 )
return 366;
else
return 365;
}
int Day( int year , int month)
{
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
return 31;
if(month==4||month==6||month==9||month==11)
return 30;
if(month==2&&leap(year)==366)
return 29;
else
return 28;
}
int get_solar_total( int year, int month)
{
int total;
int temp_num;
total=0;
for(temp_num=1900;temp_num<year;temp_num++)
total+=leap(temp_num);
for(temp_num=1;temp_num<month;temp_num++)
total+=Day(year,temp_num);
return total;
}
int solar_lunar( int kp_year, int kp_month, int kp_day)
{
int total_day=0;
int run_yue_flag=0,run_yue=0,year_flag=0;
if(kp_year<1900 || kp_year>2050 || kp_month>12 || kp_month==0 || (kp_year==1900 && kp_month==1) )
return 0;
if(kp_day>Day(kp_year,kp_month) || kp_day==0)
return 0;
total_day=get_solar_total( kp_year, kp_month)+kp_day-30;
lunar_year=1900;
while(total_day>385)
{
total_day-=get_lunar_year_total(lunar_year);
lunar_year++;
}
if(total_day>get_lunar_year_total(lunar_year))
{
total_day-=get_lunar_year_total(lunar_year);
lunar_year++;
}
run_yue=get_leap_month(lunar_year);
if(run_yue)
run_yue_flag=1;
else
run_yue_flag=0;
if(total_day==0)
{
lunar_day=get_lunar_month_total(lunar_year,12);
lunar_month=12;
}
else
{
lunar_month=1;
while(lunar_month<=12)
{
if( run_yue_flag==1 && lunar_month==(run_yue+1) )
{
if(total_day>get_leap_month_day(lunar_year))
{
total_day-=get_leap_month_day(lunar_year);
}
run_yue_flag=0;
continue;
}
if( total_day> get_lunar_month_total(lunar_year,lunar_month ) )
{
total_day=total_day-get_lunar_month_total(lunar_year,lunar_month);
lunar_month++;
}
else
{
lunar_day=total_day;
break;
}
}
}
return 0;
}
#endif
#ifndef __CONSOLECOLOR__
#define __CONSOLECOLOR__
#include <windows.h>
#include <iostream>
using namespace std;
inline ostream& red(ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); //获取标准输出句柄
SetConsoleTextAttribute(hStdout,FOREGROUND_RED|FOREGROUND_INTENSITY);//设置文本颜色
return s;
}
inline ostream& yellow(ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
return s;
}
inline ostream& white(ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);//R,G,B混合就为白色
return s;
}
inline ostream& blue(ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE
|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
return s;
}
#endif