定义一个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. Luogu P1092 虫食算

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

  2. hive:join操作

    hive的多表连接,都会转换成多个MR job,每一个MR job在hive中均称为Join阶段.按照join程序最后一个表应该尽量是大表,因为join前一阶段生成的数据会存在于Reducer 的bu ...

  3. 多线程编程学习笔记——异步调用WCF服务

    接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...

  4. SpringMVC的标签库

            Spring2.0版本开始后,提供了一组功能强大的标签用来在JSP和SpringWebMVC中处理表单元素 ,可以用来访问控制器处理命令对象和绑定数据:         以下是表单标签 ...

  5. linux iptables扩展,脚本防火墙

    netfileter:防火墙内核态ip tables:防火墙用户态(管理防火墙规则) iptables的表和链表包括不同的链,链包括大量的规则4个表: raw,mangle,nat,filter5种链 ...

  6. ul+jquery自定义下拉选择框

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. SDVO-DVI-I2C-register

    关于DVI视频输出口,微软搞了个SDVO用来保护: #define SDVO_OUTPUT_FIRST   (0) #define SDVO_OUTPUT_TMDS0   (1 << 0) ...

  8. 蜻蜓FM 涉嫌诈骗投资人和广告主源代码剖析

    本文主要内容,引用自知乎的这篇文章:如何评价蜻蜓 FM 伪造用户活跃度等数据 感谢"左莫"."任正"等热心正义的网友--左莫,任正的最早的回答猜测已经被蜻蜓FM ...

  9. file_get_contents函数不能使用的解决方法

    今天开发微信公众平台的时候 使用file_get_contents 去获得token 结果一直返回false.百度了一下,大部分都是说用curl 偶然发现可能是openssl没有开启的问题,开启ope ...

  10. linux下驱动模块化编译,动态加载以及卸载

    步骤:: 1.编写first_driver_hello.c文件,将其放在/linux2.6.32/drivers/char路径下: 2.在/linux2.6.32/drivers/cha/Kconfi ...