名称:日期类
功能:对按格式如(2000,1,1)的日期,进行合法性判断;闰年判断;判断两个日期是否是同一天;日期的输入输出;判断某个日期是这一年中的第几天;对任一日期增加指定年数、指定月数,并返回对应日期;判断任一日期是星期几
来源:c++程序设计原理与应用9.8,做了一定的内容修改和添加
日期:2017.8.17
Chrono.h
namespace Chrono {
enum class Month
{
jan = 1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec
};
enum class Day {
sunday,monday,tuesday,wednesday,thursday,friday,saturday
};
class Date {
public:
class Invalid { }; //作为抛出异常
Date(int y, Month m, int d); //检查日期合法性并初始化
Date(); //默认拷贝操作是可用的
//不改变对象的操作
int day()const { return d; }
Month month()const { return m; }
int year()const { return y; }
//改变对象的操作
void add_day(int n);
void add_month(int n);
void add_year(int n);
private:
int y;
Month m;
int d;
};
bool is_date(int y, Month m, int d);//当日期合法时返回true
bool leapyear(int y); //当y是闰年时返回true
bool operator!=(const Date& a, const Date& b);
bool operator==(const Date& a, const Date& b);
ostream& operator<<(ostream& os, const Date& d);
istream& operator>>(istream& os, const Date& d);
int daynum(const Date& d);
}
Chrono.cpp
#include "std_lib_facilities.h"
#include "Chrono.h"
using namespace Chrono;
namespace Chrono {
//成员函数的定义
Date::Date(int yy, Month mm, int dd) :y{ yy }, m{ mm }, d{dd} {
if (!is_date(yy, mm, dd)) throw Invalid{};
}
const Date& default_date() {
static Date dd{ 2001,Month::jan,1 };
return dd;
}
Date::Date():y{ default_date().year()}, m{ default_date().month()},d{ default_date().day()}{ }
void Date::add_day(int n) {
//...
}
void Date::add_month(int n) {
int rem = ((int)m + n)%12;
int integer = ((int)m + n) / 12;
if (rem == 0) {
m = Month::dec;
add_year(integer-1);
}
else {
m = Month(rem);
add_year(integer);
}
}
void Date::add_year(int n) {
if (m == Month::feb&&d == 29 && !leapyear(y + n)) { //小心闰年
m = Month::mar; //用3月1日代替2月29日
d = 1;
}
y += n;
}
//辅助函数
int daynum(const Date& d) { //某个日期是这一年中的多少天,返回这个数字
int mon[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
int sum = 0;
if (leapyear(d.year())) {
mon[1] = 29;
if (d.month() == Month::jan) {
sum += d.day();
}
else {
for (int i = 0; i<int(d.month()) - 1; i++) sum += mon[i];
sum += d.day();
}
}
else {
if (d.month() == Month::jan) {
sum += d.day();
}
else {
for (int i = 0; i<int(d.month()) - 1; i++) sum += mon[i];
sum += d.day();
}
}
return sum;
}
bool is_date(int y, Month m, int d)
{
//假设y是合法的
if(d <= 0) return false;
if (m < Month::jan || Month::dec < m) return false;
int days_in_month = 31;
switch (m)
{
case Month::feb:
days_in_month = (leapyear(y)) ? 29 : 28;
break;
case Month::apr:case Month::jun:case Month::sep:case Month::nov:
days_in_month = 30;
break;
}
if (days_in_month < d)return false;
return true;
}
bool leapyear(int y)//闰年:能被4整除且不能被100整除或者能被400整除的年份
{
return ( y%4 == 0 && y%100 != 0 || y%400 == 0 );
}
bool operator==(const Date& a, const Date&b) {
return a.year() == b.year() && a.month() == b.month() && a.day() == b.day();
}
bool operator!=(const Date& a, const Date&b) {
return !(a == b);
}
ostream& operator<<(ostream& os, const Date& d) {
return os << '(' << d.year() << ',' << (int)d.month() << ',' << d.day() << ')';
}
istream& operator>>(istream& is, Date& dd) {
int y, m, d;
char ch1, ch2, ch3, ch4;
is >> ch1 >> y >> ch2 >> m >> ch3 >> d >> ch4;
if (!is) return is;
if (ch1 != '(' || ch2 != ',' || ch3 != ',' || ch4 != ')') {
is.clear(ios_base::failbit); //设置failbit
return is;
}
dd = Date(y, Month(m), d);
return is;
}
ostream& operator<<(ostream& os, const Day& d) {
switch (d)
{
case Day::monday: return os << "monday";
case Day::tuesday: return os << "tuesday"; ;
case Day::wednesday: return os << "wednesday";
case Day::thursday: return os << "thursday";
case Day::friday: return os << "friday" ;
case Day::saturday: return os << "saturday";
case Day::sunday: return os << "sunday";
}
}
Day day_of_week(const Date& d) {
int y = d.year();
int m = (int)(d.month());
int dd = d.day();
if (d.month() == Month::jan || d.month() == Month::feb) {
m += 12;
y--;
}
int iWeek = (dd + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
switch (iWeek)
{
case 0: return Day::monday;
case 1: return Day::tuesday;
case 2: return Day::wednesday;
case 3: return Day::thursday;
case 4: return Day::friday;
case 5: return Day::saturday;
case 6: return Day::sunday;
}
}
}
int main() {
cout << "请输入一个日期" << endl;
Date date;
cin >> date;
if (is_date(date.year(), date.month(), date.day())) {
cout << "日期合法" << endl;
}
else {
cout << "日期非法" << endl;
return 1;
}
//date.add_year(1);
//cout << date << endl;
date.add_month(12);
cout << date << "今天是:"<<day_of_week(date)<<endl;
Date dd(date);
Date d3;
d3=dd;
cout <<"今天是今年中的第"<< daynum(dd)<<"天!"<<endl;
return 0;
}