定义一个Date类,包含三个属性年、月、日

实现了如下功能:

  1. 年月日的增加、减少:2017年10月1日加上100个月30天是2025年5月31日
  2. 输出某天是星期几:2017年10月1日是星期日
  3. 判断某一年是否是闰年:2020年是闰年
  4. 下一个工作日(周末)日期:2010年10月2日下一个周末是10月8日
 class Date
{
public:
Date();
Date(int yy, Month mm, int dd);
int day() const { return m_day; }
int year() const { return m_year; }
Month month() const { return m_month; } void add_day(int dd);//增加或减少天数
void add_month(int mm);//增加或减少月份
void add_year(int yy);//增加或减少年份 private:
int m_year;
Month m_month;
int m_day;
};
//判断日期是否合法
bool is_date(int y, Month m, int d);
//判断是否为闰年
bool leapyear(int y);
//两个Date是否相等
bool operator==(const Date &a, const Date &b);
bool operator!=(const Date &a, const Date &b);
//Date输入输出
ostream &operator<<(ostream &os, const Date &d);
istream &operator>>(istream &is, Date &dd);
//今天是星期几
Day day_of_week(const Date &date);
ostream &operator<<(ostream &os, const Day &d);
//下一个周末
Date next_Sunday(const Date &d);
//下一个工作日
Date next_weekday(const Date &d);

具体的实现代码如下:

 #include <iostream>
#include <vector>
#include <string> using std::istream;
using std::ostream;
using std::vector;
using std::ios_base;
using std::string; namespace Chrono
{
class InvalidDate
{
public:
std::string what() { return "InValid Date Occured"; };
}; enum class Month
{
jan = , //January
feb, //February
mar, //March
apr, //April
may, //May
jun, //June
jul, //July
aug, //August
sep, //September
oct, //October
nov, //November
dec //December
}; enum class Day
{
sun, //sunday
mon, //monday
tue, //tuesday
wed, //wednesday
thu, // thursday
fri, //friday
sat //saturday
}; class Date
{
public:
Date();
Date(int yy, Month mm, int dd);
int day() const { return m_day; }
int year() const { return m_year; }
Month month() const { return m_month; } void add_day(int dd);
void add_month(int mm);
void add_year(int yy); private:
int m_year;
Month m_month;
int m_day;
}; bool is_date(int y, Month m, int d);
bool leapyear(int y);
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 &is, Date &dd);
Day day_of_week(const Date &date);
ostream &operator<<(ostream &os, const Day &d); Date next_Sunday(const Date &d);
Date next_weekday(const Date &d); ////////////////////////////////////////////////////////////////////////////////
//Implements /////
////////////////////////////////////////////////////////////////////////////////
Date::Date(int yy, Month mm, int dd) : m_year(yy), m_month(mm), m_day(dd)
{
if (!is_date(yy, mm, dd))
throw InvalidDate{};
} const Date &default_date()
{
static const Date d{, Month::jan, };
return d;
} Date::Date() : m_year(default_date().year()),
m_month(default_date().month()),
m_day(default_date().day()) {} void Date::add_day(int dd)
{
if (dd > )
{
for (; dd > ; --dd)
{
int temp_d = m_day + ;
switch (month())
{
case Month::feb:
if ((leapyear(m_year) && temp_d > ) || (!leapyear(m_year) && temp_d > ))
{
temp_d = ;
m_month = Month::mar;
}
break;
case Month::apr:
case Month::jun:
case Month::sep:
case Month::nov:
if (temp_d > )
{
temp_d = ;
m_month = Month((int)m_month + );
}
break;
case Month::dec:
if (temp_d > )
{
temp_d = ;
m_month = Month::jan;
m_year += ;
}
break;
default:
if (temp_d > )
{
temp_d = ;
m_month = Month((int)m_month + );
}
break;
}
m_day = temp_d;
}
}
else if (dd < )
{
for (; dd < ; ++dd)
{
int temp_d = day() - ;
if (temp_d <= )
{
switch (month())
{
case Month::jan:
m_month = Month::dec;
temp_d = ;
m_year -= ;
break;
case Month::mar:
m_month = Month::feb;
if (leapyear(m_year))
temp_d = ;
else
temp_d = ;
break;
case Month::feb:
case Month::apr:
case Month::jun:
case Month::oct:
case Month::sep:
case Month::nov:
temp_d = ;
m_month = Month((int)m_month - );
break;
default:
temp_d = ;
m_month = Month((int)m_month - );
break;
}
}
m_day = temp_d;
}
}
} void Date::add_month(int month)
{
int temp_y = month / + m_year;
int temp_m = month % + (int)m_day; if (temp_y <= )
{
temp_y--;
temp_m = temp_m + ;
}
else if (temp_m > )
{
temp_y++;
temp_m = temp_m - ;
}
m_year = temp_y;
m_month = Month(temp_m);
switch (m_month)
{
case Month::feb:
if (leapyear(m_year) && m_day > )
m_day = ;
else if (!leapyear(m_year) && m_day > )
m_day = ;
break;
case Month::apr:
case Month::jun:
case Month::sep:
case Month::nov:
if (m_day > )
m_day = ;
default:
break;
}
} void Date::add_year(int n)
{
if (month() == Month::feb && day() == && !leapyear(m_year + n))
m_day = ;
m_year += n;
} bool is_date(int y, Month m, int d)
{
if (d <= )
return false;
if (m < Month::jan || m > Month::dec)
return false;
int days_in_month;
switch (m)
{
case Month::feb:
days_in_month = leapyear(y) ? : ;
break;
case Month::apr:
case Month::jun:
case Month::sep:
case Month::nov:
days_in_month = ;
break;
default:
days_in_month = ;
break;
}
if (days_in_month < d)
return false;
return true;
} // https://en.wikipedia.org/wiki/Leap_year#Algorithm
bool leapyear(int y)
{
if (y % != )
return false;
else if (y % != )
return true;
else if (y % != )
return false;
return true;
}
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() << ')';
} ostream &operator<<(ostream &os, const Day &d)
{
vector<string> weekdays{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
os << weekdays[(int)d];
return os;
} // format (2017,5,23)
istream &operator>>(istream &is, Date &d)
{
int yy, mm, dd;
char ch1, ch2, ch3, ch4;
is >> ch1 >> yy >> ch2 >> mm >> ch3 >> dd >> ch4;
if (!is)
return is;
if (ch1 != '(' || ch2 != ',' || ch3 != ',' || ch4 != ')')
is.clear(ios_base::failbit);
d = Date{yy, Month(mm), dd};
return is;
} // https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html
Day day_of_week(const Date &date)
{
int y = date.year();
int m = (int)date.month();
int d = date.day();
y -= m < ;
int day_of_week = (y + y / - y / + y / + "-bed=pen+mad."[m] + d) % ;
return Day(day_of_week);
}
Date next_Sunday(const Date &d)
{
Date d1 = d;
while (day_of_week(d1) != Day::sun)
{
d1.add_day();
}
return d1;
} Date next_weekday(const Date &d)
{
Date d1 = d;
if (day_of_week(d1) == Day::sat)
d1.add_day();
else if (day_of_week(d1) == Day::fri)
d1.add_day();
else
d1.add_day();
return d1;
}
}

代码实现

C++实现Date日期类的更多相关文章

  1. javascript Date日期类

      四.Date日期类 迁移时间:2017年5月27日18:43:02 Author:Marydon (一)对日期进行格式化(日期转字符串) 自定义Date日期类的format()格式化方法 方式一: ...

  2. 常用类--Date日期类,SimpleDateFormat日期格式类,Calendar日历类,Math数学工具类,Random随机数类

    Date日期类 Date表示特定的时间,精确到毫秒; 构造方法: public Data() public Date(long date) 常用方法: public long getTime() pu ...

  3. Date日期类,Canlendar日历类,Math类,Random随机数学类

    Date日期类,SimpleDateFormat日期格式类 Date  表示特定的时间,精确到毫秒 常用方法 getTime() setTime() before() after() compareT ...

  4. java Date日期类和SimpleDateFormat日期类格式

    ~Date表示特定的时间,精确到毫秒~构造方法:public Date()//构造Date对象并初始化为当前系统的时间public Date(long date) //1970-1-1 0:0:0到指 ...

  5. Date日期类 Calendar日历类 完成可视化日历

    package com.test; import java.text.DateFormat; import java.text.ParseException; import java.text.Sim ...

  6. 工具类 util.Date 日期类

    /** * @description format the time * @author xf.radish * @param {String} format The format your want ...

  7. java.util.Date日期类通过java语句转换成Sql(这里测试用的是oracle)语句可直接插入(如:insert into)的日期类型

    public void add(Emp emp) throws Exception{ QueryRunner runner = new QueryRunner(JdbcUtil.getDataSour ...

  8. 日期类 Date

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...

  9. JAVA基础学习之final关键字、遍历集合、日期类对象的使用、Math类对象的使用、Runtime类对象的使用、时间对象Date(两个日期相减)(5)

    1.final关键字和.net中的const关键字一样,是常量的修饰符,但是final还可以修饰类.方法.写法规范:常量所有字母都大写,多个单词中间用 "_"连接. 2.遍历集合A ...

随机推荐

  1. C语言老司机学Python (四)

    字符串格式化: 可以使用类似c语言中sprintf函数的方法进行格式化,但是函数名称是print() 如:print('常量 PI 的值近似为:%5.3f.'  %  var_PI) 注意var_PI ...

  2. mysql:联合查询

    SELECT t1.name, t2.salary  FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name; 可以对数据表使用别 ...

  3. Hibernate入门这一篇就够了

    前言 本博文主要讲解介绍Hibernate框架,ORM的概念和Hibernate入门,相信你们看了就会使用Hibernate了! 什么是Hibernate框架? Hibernate是一种ORM框架,全 ...

  4. 一个可以自由定制外观、支持拖拽消除的MaterialDesign风格Android BadgeView

    为了尊重作者,先放上链接:https://github.com/qstumn/BadgeView BadgeView 一个可以自由定制外观.支持拖拽消除的MaterialDesign风格Android ...

  5. DOS下串口通信程序来传送文件的源代码

    接收程序: #include <dos.h>#include <fstream.h>#include <conio.h>#include <stdio.h&g ...

  6. 笔记︱金融风险控制基础常识——巴塞尔协议+信用评分卡Fico信用分

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 本笔记源于CDA-DSC课程,由常国珍老师主讲 ...

  7. GStreamer 简化 Linux 多媒体开发

    Streamer 是 GNOME 桌面环境下用来构建流媒体应用的开源多媒体框架(framework),其目标是要简化音/视频应用程序的开发,目前已经能够被用来处理像 MP3.Ogg.MPEG1.MPE ...

  8. 异常-----freemarker.template.TemplateException: Error executing macro: write

    freemarker自定义标签 1.错误描述 六月 05, 2014 11:31:35 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严 ...

  9. C#图解教程 第八章 表达式和运算符

    表达式和运算符 表达式字面量 整数字面量实数字面量字符字面量字符串字面量 求值顺序 优先级结合性 简单算术运算符求余运算符关系比较运算符和相等比较运算符递增运算符和递减运算符条件逻辑运算符逻辑运算符移 ...

  10. 【BZOJ2959】长跑(Link-Cut Tree,并查集)

    [BZOJ2959]长跑(Link-Cut Tree,并查集) 题面 BZOJ 题解 如果保证不出现环的话 妥妥的\(LCT\)傻逼题 现在可能会出现环 环有什么影响? 那就可以沿着环把所有点全部走一 ...