C++实现Date日期类
定义一个Date类,包含三个属性年、月、日
实现了如下功能:
- 年月日的增加、减少:2017年10月1日加上100个月30天是2025年5月31日
- 输出某天是星期几:2017年10月1日是星期日
- 判断某一年是否是闰年:2020年是闰年
- 下一个工作日(周末)日期: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日期类的更多相关文章
- javascript Date日期类
四.Date日期类 迁移时间:2017年5月27日18:43:02 Author:Marydon (一)对日期进行格式化(日期转字符串) 自定义Date日期类的format()格式化方法 方式一: ...
- 常用类--Date日期类,SimpleDateFormat日期格式类,Calendar日历类,Math数学工具类,Random随机数类
Date日期类 Date表示特定的时间,精确到毫秒; 构造方法: public Data() public Date(long date) 常用方法: public long getTime() pu ...
- Date日期类,Canlendar日历类,Math类,Random随机数学类
Date日期类,SimpleDateFormat日期格式类 Date 表示特定的时间,精确到毫秒 常用方法 getTime() setTime() before() after() compareT ...
- java Date日期类和SimpleDateFormat日期类格式
~Date表示特定的时间,精确到毫秒~构造方法:public Date()//构造Date对象并初始化为当前系统的时间public Date(long date) //1970-1-1 0:0:0到指 ...
- Date日期类 Calendar日历类 完成可视化日历
package com.test; import java.text.DateFormat; import java.text.ParseException; import java.text.Sim ...
- 工具类 util.Date 日期类
/** * @description format the time * @author xf.radish * @param {String} format The format your want ...
- java.util.Date日期类通过java语句转换成Sql(这里测试用的是oracle)语句可直接插入(如:insert into)的日期类型
public void add(Emp emp) throws Exception{ QueryRunner runner = new QueryRunner(JdbcUtil.getDataSour ...
- 日期类 Date
import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; impor ...
- JAVA基础学习之final关键字、遍历集合、日期类对象的使用、Math类对象的使用、Runtime类对象的使用、时间对象Date(两个日期相减)(5)
1.final关键字和.net中的const关键字一样,是常量的修饰符,但是final还可以修饰类.方法.写法规范:常量所有字母都大写,多个单词中间用 "_"连接. 2.遍历集合A ...
随机推荐
- nginx笔记4-负载均衡带来的问题以及解决办法
接着笔记3,将笔记三的改造一下,现在分别启动两个Tomcat,在页面获取session.如图所示: tomcat2的session: tomcat1的session: 根据上图发现,每个tomcat取 ...
- linux ftp及C/S服务架构
乱码转换工具使用convmv软件:windows中文字符编码为GB2312 linux中文字符编码为utf-8选项:-f:源文件中中文字符编码-t:转换成字符编码-r:代表递归--notest:不测试 ...
- java字符流
网上有很多地方说inputStreamReader和outStreamWriter.BufferedReader和BufferedWriter都是字符流.不过也有地方说inputStreamReade ...
- 《实战Nginx》读书笔记
最近今天读了一本书叫做<实战Nginx:取代Apache的高性能Web服务器>,看后对Nginx 了解了不少.但是还有很多地方不是很了解.不过此书可以作为一本参考手册来使用,里面的讲解很详 ...
- vc++怎么可以直接刷掉MBR?搞笑的吧
FILE * fd=fopen("\\\\.\\PHYSICALDRIVE0","rb+"); char buffer[512]; fread(buffer,5 ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- Linux之23个重要命令
作为工作几年的Linux运维老司机,总结了Linux命令行的常用的一些用法,希望对您有所收获. 1. 搜索 在vi和vim中如果打开一个很大的文件,不容易找到对应的内容,可以使用自带的搜索关键字进行搜 ...
- 使用定时器限制点击按钮发送短信(附源码)--JavaScript小案例
不说多哈,有注释哦,直接贴代码了哈,有疑问请追评呢…… 1.禁用按钮: this.disabled = "disabled"(this指按钮)或: this.disabled = ...
- java中垃圾回收机制和引用类型
在java中JDK1.2版本以后,对象的引用类型分为四种,从高到低依次为:强引用.软引用.弱引用.虚引用. ①强引用的特点:垃圾回收机制绝不会回收它,即使内存不足时,JVM宁愿抛出OutOfMemor ...
- Luogu3613 睡觉困难综合征
题面描述https://www.luogu.org/problemnew/show/3613 原题NOI2014起床困难综合症https://www.luogu.org/problemnew/show ...