2019年3月14日 星期四

【CMoney - HW3】 C++ 輸入日期顯示星期、推算幾天前後的日期、輸入年月輸出月曆

以下列enum與struct設計日期星期查詢程式。
須考慮閏年因素
已知條件為: 2019/3/12 TUE


實現功能:
1. 以日期查詢星期
2. 以某日往後及往前若干天推算日期
3. 以月曆型式輸出某給定年月



#include <iostream>
#include<iomanip>
#include "main.h"
using namespace std;

int mdays[12] = {31, 28, 31, 30, 31, 30,31, 31, 30, 31, 30, 31};

/* 第一題、 以日期查詢星期-----------------------*/
WeekDay QueryWeekDay( int Y, Month M, int D ){
int result = 0; // 判斷需要往後加, 還是往前

Date origin = { 2019, March, 12, Tuesday};

result = (Y>origin.year)?1:((Y==origin.year)?((M>origin.month)?1:((M==origin.month)?((D>=origin.day)?1:0):0)):0);

while(!(origin.year == Y && origin.month == M && origin.day == D) )
{
if(result == 1) 
Tomorrow( origin );
else
Yesterday( origin );
}
return origin.weekday;
}
void Tomorrow(Date & date){
if(checkYear(date.year)==1) mdays[February - 1] = 29;
if(checkYear(date.year)==0) mdays[February - 1] = 28;

if(date.day == mdays[date.month - 1])
{
date.day = 1;
if(date.month == December )
{
date.month = January;
date.year++;
}
else
date.month = (Month) ((int)date.month + 1);
}
else
date.day++;

if (date.weekday == Sunday)
date.weekday = Monday;
else
date.weekday = (WeekDay)((int)date.weekday + 1) ;

}
void Yesterday(Date & date){
if(checkYear(date.year)) mdays[February - 1] = 29;
else                        mdays[February - 1] = 28;
if(date.day == 1)
{
if(date.month == January )
{
date.month = December;
date.year--;
date.day = mdays[date.month - 1];
}
else
{
date.month = (Month) ((int)date.month - 1);
date.day = mdays[date.month - 1];
}
}
else
date.day--;

if (date.weekday == Monday)
date.weekday = Sunday;
else
date.weekday = (WeekDay)((int)date.weekday - 1);
}
/*------------------------------------第一題結束 */

/* 第二題、 以某日往後及往前若干天推算日期-------*/
Date QueryNDaysBefore( const Date & date, int ndays ) {
Date d = date;
for(int i = 0; i < ndays; i++)
Tomorrow(d);

d.weekday = QueryWeekDay(d.year, d.month, d.day);
return d;
}
Date QueryNDaysAfter( const Date & date, int ndays ) {
Date d = date;

for(int i = 0; i < ndays; i++)
Yesterday(d);

d.weekday = QueryWeekDay(d.year, d.month, d.day);
return d;
}
/*------------------------------------第二題結束 */

/* 第三題、 以月曆型式輸出某給定年月 ------------*/
void OutputCalendar( int y, Month m ) {
//設計方式:
//一、一年有365天(剛好是52個禮拜又一天)。西元1年1月1日為星期一,那西元2年1月1日
// 就應該是星期二囉,所以必須知道從西元1年到該年到底有多少次潤年。
//二、依此方式就可以推算出每月的1號是星期幾了。
//三、逢四年一閏,百年不閏,逢四百年又一閏

    int i;
    int remainder; //定義欲求月曆之年份第一個月份之餘數(即該年份1月1日為星期幾)
    int year; //欲求月曆之年份
int month; //欲求月曆之月份
int day[12]={31,28,31,30,31,30,31,31,30,31,30,31}; //定義12月份之各月份天數
    int dayrem; //求出欲求該年份1月1日之餘數
 
    cout << endl << endl;
    remainder=(y-1+(y-1)/4-(y-1)/100+(y-1)/400)%7;//己知西元1年1月1日為星期一
     //求出欲求該年份第一個月之餘數必須計算閏年,若該年可
     //被100除盡,則該年不是閏年,但若該年可被400除盡,它也是閏年
     //求出欲求該年份前一年12月31日星期幾
    if ((y%4 == 0 && y%100 != 0) || y%400 == 0)
    {
if (m>=2) //若該年是閏年則餘數+1,2月份也改為29天
{
day[1]=29;
}
    }
 
    for (i=0;i<(m-1);i++) //求出欲求該年份1月1日之總天數
    {
     remainder+=day[i];
    }
 
    dayrem=(remainder+1)%7; //求出欲求該月份1日星期幾(因為從星期日計算故+1)
 
    cout <<" 西元" << y << "年" << m << "月" << endl;
    cout <<" 日 一 二 三 四 五 六" << endl;
 
    for (i=0;i<dayrem;i++) //該月份1日前之星期幾填入空格
{
    cout << setw(3) << setfill(' ') << "";
}

    int count = dayrem % 7; //該月份1日從星期幾開始依序填入日期
 
for (i=0;i<day[m-1];i++)
    {
cout << setw(3) << setfill(' ') << i+1; //3個字為一組,不足填入空格
if (count>=6) //每週六後換行
{
cout << endl;
count=0;
}
else
{
count++;
}
    }
    cout << endl;
}
/*------------------------------------第三題結束 */

/* 確認是否為閏年*/
int checkYear(int n){
if(n % 400 == 0 || (n % 4 == 0 && n % 100 != 0))
return 1;
else
return 0;
}

/* 顯示星期幾 */
void showWeekday(WeekDay d){
switch(d)
{
case 1:cout << "星期一\n";break;
    case 2:cout << "星期二\n";break;
    case 3:cout << "星期三\n";break;
    case 4:cout << "星期四\n";break;
    case 5:cout << "星期五\n";break;
    case 6:cout << "星期六\n";break;
    case 7:cout << "星期日\n";break;
}
}

/* 顯示年月日星期 */
void showData(const Date & date){
cout << date.year << "年" << date.month << "月" << date.day << "日星期" << date.weekday << endl;
}


void QuestionOne(void){
int month;
Date buffer;
cout << "請輸入想要查詢的年:" ;
cin  >> buffer.year;
cout << "請輸入想要查詢的月:" ;
cin >> month;
cout << "請輸入想要查詢的日:" ;
cin  >> buffer.day;

showWeekday(QueryWeekDay(buffer.year, (Month)month, buffer.day));
// showWeekday(QueryWeekDay(2000, October, 1));
}
void QuestionTwo(void){
int select1;
int y,m,d,wkd;
Date D = {1992, May, 16,Saturday};
Date Da, Db;

cout << "請輸入基準年為何:";
cin  >> y ;
cout << "請輸入基準月為何:";
cin  >> m;
cout << "請輸入基準日為何:";
cin  >> d;
cout << "請輸入基準星期為何:";
cin  >> wkd;
cout << "請輸入幾天後或幾天前日期為何:";
cin  >> select1;

showData(QueryNDaysBefore(D, select1));
showData(QueryNDaysAfter(D, select1));
}
void QuestionThree(void){
int y, m;
cout << "請輸入查詢年分:";
cin  >> y ;
cout << "請輸入查詢月分:";
cin  >> m;

OutputCalendar( y, (Month)m );
}


int main(void){
int select = 0, loop = 1;
do{
cout << "\n請輸入數字 1 ~ 3 選擇答案 \n輸入其他字元則離開程式:";
cin  >> select;
switch(select)
{
case 1:QuestionOne();break;
case 2:QuestionTwo();break;
case 3:QuestionThree();break;
default:loop = 0;break;
}
}while(loop);
return 0;
}


沒有留言:

張貼留言

Android Studio IDE 錯誤

 :app:compile xxxxx JavaWithJavac FAILED An exception has occurred in the compiler (1.8.0_312). Please file a bug against the Java compiler ...