//计算将来或以前某一天是星期几
#include #include
using namespacestd;structdate
{intyear;intmonth;intday;intweekday;static int m_d[2][13];static int y_d[2];static string d_w[8];
};int date::m_d[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };int date::y_d[2] = {365, 366};string date::d_w[8] = {"", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"};int is_leap(intyear)
{//注意 year % 100 != 0//year % 4 == 0//year % 400 == 0//这三者的顺序//总共4中顺序组合,不同的顺序影响不同的计算效率
if (year % 100 != 0 && year % 4 == 0 || year % 400 == 0)
{return 1;
}else{return 0;
}
}bool get_date(const string& str, date&dt)
{
dt.year= 0;
dt.month= 0;
dt.day= 0;int y(0), m(0), d(0);stringsy, sm, sd;int f = 1;bool full = false, pass_d = false;for (string::size_type i = 0; i != str.size(); ++i)
{//if (isdigit(static_cast(str[i])))//该语句导致isctype.c中断言错误:unsigned(c + 1) <= 256//故改为:
if (str[i] >= '0' && str[i] <= '9')
{
pass_d= false;if (f == 1)
{
sy+=str[i];if (sy.size() == 4)
{++f;
full= true;
}
}else if (f == 2)
{
sm+=str[i];if (sm.size() == 2)
{++f;
full= true;
}
}else if (f == 3)
{
sd+=str[i];if (sd.size() == 2)
{++f;
full= true;
}
}else if (f > 3)
{return false;
}
}else{if (pass_d == false)
{
pass_d= true;if (full == true)
{
full= false;
}else{++f;/*if (f > 4)
{
return false;
}*/}
}else{continue;
}
}
}
y=atoi(sy.c_str());
m=atoi(sm.c_str());
d=atoi(sd.c_str());if (m < 1 || m > 12)
{return false;
}else{if (d < 1 || d >date::m_d[is_leap(y)][m])
{return false;
}
}
dt.year=y;
dt.month=m;
dt.day=d;return true;
}string uni_date(const date&dt)
{stringret;char tmp[1000];
itoa(dt.year, tmp,10);
ret+=tmp;
ret+= '-';if (dt.month < 10)
{
ret+= '0';
}
itoa(dt.month, tmp,10);
ret+=tmp;
ret+= '-';if (dt.day < 10)
{
ret+= '0';
}
itoa(dt.day, tmp,10);
ret+=tmp;returnret;
}string cal_weekday(date&dt)
{string dt_str =uni_date(dt);string ref_str = "20130802";
date ref_dt;
ref_dt.year= 2013;
ref_dt.month= 8;
ref_dt.day= 2;
ref_dt.weekday= 5;boolfut;
date bigger, smaller;if (dt_str >=ref_str)
{
fut= true;
bigger=dt;
smaller=ref_dt;
}else{
fut= false;
bigger=ref_dt;
smaller=dt;
}int smaller_days = 0, bigger_days = 0;for (int m = 1; m < smaller.month; ++m)
{
smaller_days+=date::m_d[is_leap(smaller.year)][m];
}
smaller_days+=smaller.day;for (int y = smaller.year; y < bigger.year; ++y)
{
bigger_days+=date::y_d[is_leap(y)];
}for (int m = 1; m < bigger.month; ++m)
{
bigger_days+=date::m_d[is_leap(bigger.year)][m];
}
bigger_days+=bigger.day;int diff = bigger_days -smaller_days;if(fut)
{
dt.weekday= (ref_dt.weekday + diff) % 7;
}else{
dt.weekday= ((ref_dt.weekday + 7) - (diff % 7)) % 7;
}//当为星期天时,dt.weekday为0,所以根据date::d_w[]需要做一下特殊处理
if (dt.weekday == 0)
{
dt.weekday= 7;
}returndate::d_w[dt.weekday];
}intmain()
{stringstr;while (1)
{
cout<< "输入:";
cin>>str;
date dt;
cout<< "输出:";if(get_date(str, dt))
{
cout<< uni_date(dt) <
}else{
cout<< "输入日期非法!" << endl <
}
cout<< cal_weekday(dt) <
cout<
}
}