万年历

#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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值