C++写一个Date日期类

embedded/2024/11/15 3:54:06/

一个日期类作为类和对象知识点的总结
注意:
因为历史上1582年10月是少了10天,并且闰年的计算规则在1582年前后是不同的,因此计算某一天是周几,直接采用了倒推的方式确定公元1年1月1日是周几,然后反过来写的。(仅仅为了省事)

Date.h

#pragma once
/* 一个类可以重载那些运算符,取决于哪些运算符对这个类型有意义! */
class Date {
public://对Date类声明友元friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in,  Date& d);//构造函数Date(int year=1,int month = 1,int day = 1):_year(year),_month(month),_day(day){//检查日期合法性if (!checkDate()) {assert(checkDate());}}//拷贝构造Date(const Date& d) :_year(d._year),_month(d._month),_day(d._day){}//赋值重载 d1=d2=d3,最后返回d1Date& operator=(const Date& d){//防止自我赋值if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}bool isLeapYear(int year) {if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))return true;return false;}int getLeapNum(int begin, int end) {if (begin > end)	return 0;int leap1 = (begin - 1) / 4 - (begin - 1) / 100 + (begin - 1) / 400;int leap2 = end / 4 - end / 100 + end / 400;return leap2 - leap1;}//获取某年某月天数,频繁调用->放在类里定义作为内联//构造频繁,直接放在类里面当作内联int getMonthDay(int year, int month) {static int months[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//如果是2月且闰年if (_month == 2 && isLeapYear(year))return 29;return months[month];}//日期合法性bool checkDate() {if (_year >= 1&& _month && _month < 13&& _day>0 && _day <= getMonthDay(_year, _month)){return true;}return false;}//比较运算符bool operator==(const Date& d);bool operator!=(const Date& d);bool operator>(const Date& d);bool operator<(const Date& d);bool operator>=(const Date& d);bool operator<=(const Date& d);//日期+-天数Date operator+(int day);Date& operator+=(int day);Date operator-(int day);Date& operator-=(int day);//operator++Date& operator++();//前置Date operator++(int);//后置//日期-日期int operator-(const Date& d);//operator--Date& operator--();Date operator--(int);int operator-(const Date& d) const;//计算是周几string DayofWeek();
private:int _year;int _month;int _day;
};//cout << d1 << d2,频繁调用,函数声明和定义不分离 直接内联
inline ostream& operator<<(ostream& out, const Date& d) {out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}//cin>>d1>>d2, 需要改变Date对象 不能用const引用
inline istream& operator>>(istream& in,Date& d) {in >> d._year >> d._month >> d._day;//检查输入日期合法assert(d.checkDate());return in;
}

Date.cpp

#define _CRT_SECURE_NO_WARNINGS	
#include<iostream>
#include<assert.h>
using namespace std;#include "Date.h"//比较运算符
bool Date::operator==(const Date& d) {return _year == d._year&& _month == d._month&& _day == d._day;
}
bool Date::operator!=(const Date& d) {return !(*this == d);
}
bool Date::operator>(const Date& d) {if (_year > d._year || _year == d._year && _month > d._month ||_year == d._year && _month == d._month && _day > d._day){return true;}return false;
}
bool Date::operator<(const Date& d) {return !(*this >= d);
}
bool Date::operator>=(const Date& d) {return *this == d || *this > d;
}
bool Date::operator<=(const Date& d) {return !(*this > d);
}//日期+=天数: d1+=d2+=100
Date& Date::operator+=(int day) {//处理day是负数的情况: +=负数 -> -=正数if (day < 0) {return *this -= -day;}//先把天数加上,然后判断是否超过当月的天数_day += day;while (_day > getMonthDay(_year, _month)) {_day -= getMonthDay(_year, _month);++_month;if (_month == 13) {++_year;_month = 1;}}return *this;
}//日期+天数 d+100是返回结果,d本身不改变
Date Date::operator+(int day) {//利用临时对象Date tmp = *this;tmp += day;return tmp;
}//日期-=天数 d1-100
Date& Date::operator-=(int day) {//-=负数-> +=正数if (day < 0) {return *this += -day;}//先减掉天数,若天数<=0 就继续借上个月的天数_day -= day;while (_day <= 0) {--_month;if (_month == 0) {_month = 12;--_year;}_day += getMonthDay(_year, _month);//借上个月}return *this;
}
Date Date::operator-(int day) {Date tmp = *this;tmp -= day;return tmp;
}//++d, 返回改变后
Date& Date::operator++() {return *this += 1;
}
//d++,返回改变前
Date Date::operator++(int) {Date tmp = *this;*this += 1;return tmp;
}//operator--
Date& Date::operator--() {return *this -= 1;
}
Date Date::operator--(int) {Date tmp = *this;*this -= 1;return tmp;
}//
//		2022-7-23   2003-4-10
//		计算2003的1月1日到2022年1月1日的差距 diff1
//		再计算处4-10和7-23分别是这一年的第几天,计算差值 diff2
//		两个差值相加即可//日期-日期 
int Date::operator-(const Date& d) {//计算 年份之间差多少天//先假设大的年份是 *this的年份int max = _year; //大的年份int min = d._year; //小的年份if (_year < d._year) {max = d._year;min = _year;}//计算 [min,max]之间的 整年中的闰年个数   整年范围: [min+1,max-1]int diff1 = (max - min) * 365 + getLeapNum(min+1,max-1);  //基础年数+闰年个数(闰年多1天)//计算分别是本年的第几天int diff2 = 0;int day1 = _day;for (int i = 1; i < _month; ++i) {day1 += getMonthDay(_year, i);}int day2 = d._day;for (int i = 1; i < d._month; ++i) {day2 += getMonthDay(d._year, i);}//diff2计算的是 *this和d 在这一年中 分别是第几天的差距,是 *this-ddiff2 = day1 - day2;//diff1计算的是 大年份比小年份差多少天,但目标要计算*this - d,如果d的年份大,要变一下符号。if (max == d._year) {diff1 *= -1;}return diff1 + diff2;
}//周几
string Date::DayofWeek() {//计算1.1.1到现在差多少天, 1.1.1默认周1static string weeks[] = { "周一","周二","周三","周四","周五","周六","周天" };//0对应周一 公园1,1,1是周1int n = *this - Date(1, 1, 1);int weekday = 1;	//逆推1,1,1是周2weekday += n;return weeks[weekday%7];
}

测试代码

//test.cpp
//测试日期比较大小
void test_Date1()
{Date d1;Date d2(2022, 7, 15);cout << (d1 == d2) << endl;cout << (d1 <= d2) << endl;cout << (d1 >= d2) << endl;cout << (d1 < d2) << endl;}//测试+= 
void test_Date2()
{Date d1(2022, 7, 23);Date d2(d1);d1 += 86;d1 += 453;d1 += 4000;Date d3 = d2 + 86;d1 += -4000;d1 += -453;d1 += -86;}//测试 -=
void test_Date3()
{Date d1(2022, 7, 23);d1 -= 86;d1 -= 453;d1 -= 4000;
}//测试 ++ 和 --
void test_Date4()
{Date d1(2022, 7, 23);++d1;--d1;Date d2 = d1 + 1;
}//测试日期 - 日期
void test_Date5()
{Date d1(2022, 7, 23);Date d2(2022, 5, 5);Date d3(2022, 8, 15);Date d4(2020, 3, 25);Date d5(2025, 12, 25);cout << (d2 - d1) << endl;cout << (d3 - d1) << endl;cout << (d4 - d1) << endl;cout << (d5 - d1) << endl;}//测试 << >>
void test_Date6()
{Date d1(2024, 11, 13);cout << d1 << endl;Date d2;cin >> d2;cout << d1 << d2 << endl;
}//测试周几
void test_Date7()
{Date d1(2024,11, 13);cout << d1.DayOfWeek() << endl;
}
int main()
{//test_Date1();//test_Date2();//test_Date3();//test_Date4();//test_Date5();//test_Date6();test_Date7();return 0;
}

http://www.ppmy.cn/embedded/137334.html

相关文章

Python操作系统交互:subprocess库的基本应用

Python 操作系统交互&#xff1a;subprocess 库的基本应用 在日常的 Python 编程中&#xff0c;操作系统交互是一个常见的需求。无论是调用外部命令、与操作系统进程进行交互&#xff0c;还是在 Python 中运行脚本&#xff0c;subprocess 庋是一个强大的工具。它为 Python 提供…

信息安全建设方案,网络安全等保测评方案,等保技术解决方案,等保总体实施方案(Word原件)

1 概述 1.1 项目简介 1.2 测评依据 2 被测信息系统情况 2.1 定级情况 2.2 承载的业务情况 2.3 网络结构 2.4 被测对象资产 2.5 上次测评问题整改情况说明 3 测评范围与方法 3.1 测评指标 3.1.1 安全通用要求指标 3.1.2 安全扩展要求指标 3.1.3 其他安全要求指标 3.1.4 不适用安…

【LeetCode】【算法】22. 括号生成

LeetCode 22. 括号生成 题目描述 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数&#xff0c;用于能够生成所有可能的并且 有效的 括号组合。 解题思路 天天到处看答案&#xff0c;看的灵神的解题思路回溯不会写&#xff1f;套路在此&#xff01;&#xff08;Pyth…

实现扫码挪车,微信通知、打电话(内有免费部署静态网站+免费域名的方法)

先上静态网页界面&#xff0c;有需要的自取&#xff0c;随便改改样式即可。 htmlcssjs <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, ini…

JS爬虫实战之TikTok_Shop验证码

TikTok_Shop验证码逆向 逆向前准备思路1- 确认接口2- 参数确认3- 获取轨迹参数4- 构建请求5- 结果展示 结语 逆向前准备 首先我们得有TK Shop账号&#xff0c;否则是无法抓取到数据的。拥有账号后&#xff0c;我们直接进入登录。 TikTok Shop 登录页面 思路 逆向步骤一般分为…

Java集合基础——针对实习面试

目录 Java集合基础什么是Java集合&#xff1f;说说List,Set,Queue,Map的区别&#xff1f;说说List?说说Set?说说Map&#xff1f;说说Queue?为什么要用集合&#xff1f;如何选用集合&#xff1f; Java集合基础 什么是Java集合&#xff1f; Java集合&#xff08;Java Collect…

大模型推理优化技术-KV Cache量化

近两年大模型火出天际&#xff1b;同时&#xff0c;也诞生了大量针对大模型的优化技术。本系列将针对一些常见大模型优化技术进行讲解。 大模型推理优化技术-KV Cache大模型推理服务调度优化技术-Continuous batching大模型底显存推理优化-Offload技术大模型推理优化技术-KV C…

【Linux】ubuntu安装图形化界面步骤

一、ubuntu 安装桌面环境 1、更新软件包列表&#xff08;命令↓&#xff09; sudo apt update 2、安装桌面环境GNOME&#xff08;命令↓&#xff09; sudo apt install ubuntu-desktop 3、安装完成后需要重启服务器&#xff08;服务器重启命令↓&#xff09; sudo reboot 二、…