时间类的实现

news2024/11/20 20:59:52

在现实生活中,我们常常需要计算某一天的前/后xx天是哪一天,算起来十分麻烦,为此我们不妨写一个程序,来减少我们的思考时间。

1.基本实现过程

为了实现时间类,我们需要将代码写在3个文件中,以增强可读性,我们将这三个文件命名为date.h date.cpp test.cpp.

这是date.h文件

#pragma once 
#include<iostream>
using namespace std;

class Date
{
	//友元
	friend void operator<<(ostream& out, const Date& d);
public:
	Date(int year = 1, int month = 1, int day = 1);
	void print();
	//inline
	int getmonday(int year, int month)
	{
		//把12个月先准备好
		static int monthDayArray[13] = { -1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		//闰年判断
		if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
		{
			return 29;
		}
		return monthDayArray[month];
	}

	//判断日期大小的函数
	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);

	//d1+=
	Date& operator+=(int day);
	Date operator+(int day);

	// d1 -=
	Date& operator-=(int day);
	// d1 - 100
	Date operator-(int day);

	// d1 - d2
	int operator-(const Date& d);

	// ++d1 -> d1.operator++();
	Date& operator++();

	// d1++ -> d1.operator++(0);
	Date operator++(int);

	Date& operator--();

	Date operator--(int);

	//void operator<<(ostream& out);

private:
	int _year;
	int _month;
	int _day;
};
void operator<<(ostream& out, const Date& d);

这是date.cpp文件

#define _CRT_SECURE_NO_WARNINGS 
#include"date.h"
Date::Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}
void Date::print()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}
//d1+=50
Date& Date::operator+=(int day)   //this  ->  d1;day->50
{
	if (day < 0)
	{
		return *this -= (-day);
	}
	_day += day;        //等价于this->_day += day;
	while (_day > getmonday(_year, _month))
	{
		_day -= getmonday(_year, _month);
		//月进位
		++_month;
		if (_month == 13)
		{
			++_year;
			_month = 1;
		}
	}
	return *this;
}

Date Date::operator+(int day)
{
	Date tmp(*this);
	tmp += day;
	return tmp;
}
// d1 -= 天数
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return *this += (-day);
	}
	_day -= day;
	while (_day <= 0)
	{
		// 借位
		--_month;
		if (_month == 0)
		{
			--_year;
			_month = 12;
		}
		_day += getmonday(_year, _month);
	}
	return *this;
}
Date Date::operator-(int day)
{
	Date tmp = *this;
	tmp -= day;
	return tmp;
}
// d1 < d2
bool Date::operator>(const Date& d)
{
	if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year && _month > d._month)
	{
		return true;
	}
	else if (_year == d._year && _month == d._month)
	{
		return _day > d._day;
	}
	return false;
}

//d1<d2
bool Date::operator<(const Date& d)
{
	return !(*this >= d);              //复用,< 就是不大于
}
bool Date::operator<=(const Date& d)
{
	return !(*this > d);
}
// d1 >= d2
bool Date::operator>=(const Date& d)
{
	return *this > d || *this == d;
}
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);
}

//顺便说一下前置++和后置++怎末写
// ++d1 -> d1.operator++();
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
// d1++ -> d1.operator++(0);//这个数多少都行,没影响的,就是++,跟你传的数没关系
Date Date::operator++(int)
{
	Date tmp = *this;
	*this += 1;

	return tmp;
}
//前置--
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
//后置--
Date Date::operator--(int)
{
	Date tmp = *this;
	*this -= 1;
	return tmp;
}
//求日期差多少天
//d1-d2
//this->d1,d->d2    (d是d2别名)
int	Date::operator-(const Date& d)
{
	//不知道d1d2谁大谁小,为了避免弄错先后关系,我们比较一下
	int flag = 1;
	Date max = *this;
	Date min = d;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}
	int n = 0;
	while (min != max)
	{
		++n;
		++min;
	}
	return n * flag;
}
void operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
}

这是test.cpp文件

#include"Date.h"
#include<math.h>
void testdate1()
{
	Date d1(2024, 11, 14);
	Date d2 = d1 + 50;
	//d1 += 50;
	d1.print();
	d2.print();
	Date d3(2024, 11, 14);
	Date d4 = d3 + 5000;
	d3 += 5000;

	d3.print();
	d4.print();
}
void testdate2()
{
	Date d1(2024, 11, 16);
	Date d2 = d1 - 50;
	//d1 -= 50;

	d1.print();
	d2.print();
	
	Date d3(2024, 11, 16);
	Date d4 = d3 - 5000;
	d3 -= 5000;

	d3.print();
	d4.print();

	Date d5(2024, 11, 16);
	d5 += -100;
	d5.print();
}
void testdate3()
{
	Date d1(2024, 11, 16);
	Date d2(2024, 11, 16);
	Date d3(2024, 10, 17);

	cout << (d1 > d2) << endl;
	cout << (d1 >= d2) << endl;
	cout << (d1 == d2) << endl;

	cout << (d1 > d3) << endl;
	cout << (d1 >= d3) << endl;
	cout << (d1 == d3) << endl;
}
void testdate4()
{
	//打印时,不要放在一坨,否则由于我们的++操作,可能导致程序本身没大问题,但是打印会出问题,导 
      致我们看不到我们想要的结果
	Date d1(2024, 11, 16);
	d1.print();
	Date d4 = d1++;   //等价于Date d4 = d1.operator++(1);这里实参传什么值都可以,只要是int就 
                        行,仅仅参数匹配
	d4.print();
	Date d3 = ++d1;   //等价于Date d3 = d1.operator++();
	d3.print();

	cout << endl;
	Date d6(2024, 11, 16);
	d6.print();
	Date d7 = ++d6;
	d7.print();
	Date d8 = d6++;
	d8.print();

	//通过对比两组实验结果,我们发现,前置++和后置++区别很大,
	//第一组,我们让后置++在前置++前面,会发现:由于后置++是先使用后++,故打印出16日,之后变为 
      17,而前置++是先++后使用,此时,17+1==18,故打印出来是18日
	//同理,可解释第二组的结果,这里不在赘述,由此可见,选取哪种++方式,要视情况而定
}
void testdate5()
{
	Date d1(2025, 3, 3);
	Date d2(2025, 1, 14);

	cout <<"还有" << abs(d1 - d2) <<"放假!"<< endl;    //abs是临时起意为了解决实际问题而加的

	int i = 100;
	//cout << d1 << "和" << i;
	cout << d1;     //这里之所以能输出年月日字样,是因为我们定义了<<运算符,是设置的一种输出流, 
                      不要和正常的cout<<弄混
	//d1 << cout;
}
int main()
{
	//testdate1();
	//testdate2();
	//testdate3();
	//testdate4();
	testdate5();
	return 0;
}

代码结果这里就不过多展示了!

2.代码优化 

这里有一个小问题~~

上述testdate5中,cout<<d1没有问题,但是当我们在想连续输出其他值时,会出现报错,我们看<ostream>里面的cout,为什么可以连续输出,因为其在输出第一个值之后,返回值仍为cout,但是,反观我们写的函数,没有返回值了!故我们需要在对其精进一下!

精进代码如下:

我们将date.cpp的输入流和输出流这样改一下!

ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}
istream& operator>>(istream& in, Date& d)
{
	cout << "请依次输入年月日:>";
	in >> d._year >> d._month >> d._day;
	return in;
}

date.h也改一下:(这里将前面用不到的函数删去了!)

#pragma once 
#include<iostream>
using namespace std;

class Date
{
	//友元
	 friend ostream& operator<<(ostream& out, const Date& d);
	 friend istream& operator>>(istream& in, Date& d);
public:
private:
	int _year;
	int _month;
	int _day;
};
// 流插入
ostream& operator<<(ostream& out, const Date& d);
// 流提取
istream& operator>>(istream& in, Date& d);

test.cpp也改一下:

void testdate6()
{
	Date d1(2024, 2, 29);
	Date d2(2023, 2, 29);
	cin >> d1 >> d2;
	cout << d1 << d2;
}
int main()
{
	testdate6();
	return 0;
}

如此一来,我们得到了我们想输出的日期! 

 

 可是,这个日期真的对吗?我们的编译器似乎太服从我们了,不管对错他都输出,但是,为了保证我们输出结果的正确性,应该加上一组日期判断,不符合常理的就让用户重新输!

3.提高正确性

我们做出如下改造:

在date.cpp文件中在定义一个函数,用于检查日期是否合理:

bool Date::checkdate()const     //为什么加const下一篇博客讲
{
	if (_month < 1 || _month > 12 || _day < 1 || _day > getmonday(_year, _month))
	{
		return false;
	}
	else
	{
		return true;
	}
}

date.cpp的流提取也要改一下: 

istream& operator>>(istream& in, Date& d)
{
	while (1)
	{
		cout << "请依次输入年月日:>";
		in >> d._year >> d._month >> d._day;
		if (d.checkdate())        //得到结果为1
		{
			break;
		}
		else                     //得到结果为0
		{
			cout << "输入的日期非法,请重新输入" << endl;
		}
	}
	return in;
}

这样我们就得到了一个功能相对健全的时间程序!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244250.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习笔记024——Ubuntu 安装 Redis遇到相关问题

目录 1、更新APT存储库缓存&#xff1a; 2、apt安装Redis&#xff1a; 3、如何查看检查 Redis版本&#xff1a; 4、配置文件相关设置&#xff1a; 5、重启服务&#xff0c;配置生效&#xff1a; 6、查看服务状态&#xff1a; 1、更新APT存储库缓存&#xff1a; sudo apt…

【时间之外】IT人求职和创业应知【35】-RTE三进宫

目录 新闻一&#xff1a;京东工业发布11.11战报&#xff0c;多项倍增数据体现工业经济信心提升 新闻二&#xff1a;阿里云100万核算力支撑天猫双11&#xff0c;弹性计算规模刷新纪录 新闻三&#xff1a;声网CEO赵斌&#xff1a;RTE将成为生成式AI时代AI Infra的关键部分 认知…

css3中的多列布局,用于实现文字像报纸一样的布局

作用&#xff1a;专门用于实现类似于报纸类的布局 常用的属性如下&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevic…

网络基础(4)IP协议

经过之前的学习对传输协议的学习&#xff0c;对于传输协议从系统底层到应用层对于socket套接字的学习已经有了一套完整的理论。 对于网络的层状结构&#xff0c;现在已经学习到了应用层和传输层: 在之前的学习中&#xff0c;通信的双方都只考虑了双方的传输层的东西&#xff0…

【图像处理识别】数据集合集!

本文将为您介绍经典、热门的数据集&#xff0c;希望对您在选择适合的数据集时有所帮助。 1 CNN-ImageProc-Robotics 机器人 更新时间&#xff1a;2024-07-29 访问地址: GitHub 描述&#xff1a; 通过 CNN 和图像处理进行机器人对象识别项目侧重于集成最先进的深度学习技术和…

Leetcode 快乐数

算法思想&#xff1a; 这段代码的目的是判断一个正整数是否是 快乐数&#xff08;Happy Number&#xff09;。根据题目要求&#xff0c;快乐数定义如下&#xff1a; 对于一个正整数&#xff0c;不断将它每个位上的数字替换为这些数字平方和。重复这个过程&#xff0c;如果最终…

探索Python PDF处理的奥秘:pdfrw库揭秘

文章目录 探索Python PDF处理的奥秘&#xff1a;pdfrw库揭秘1. 背景&#xff1a;为何选择pdfrw&#xff1f;2. pdfrw是什么&#xff1f;3. 如何安装pdfrw&#xff1f;4. 五个简单的库函数使用方法4.1 读取PDF信息4.2 修改PDF元数据4.3 旋转PDF页面4.4 提取PDF中的图片4.5 合并P…

若点集A=B则A必能恒等变换地变为B=A这一几何常识推翻直线(平面)公理

黄小宁 关键词&#xff1a;“更无理”复数 复平面z各点z的对应点z1的全体是z1面。z面平移变为z1面就使x轴⊂z面沿本身平移变为ux1轴。R可几何化为R轴&#xff0c;R轴可沿本身平移变为R′轴&#xff0c;R′轴可沿本身平移变为R″轴&#xff0c;...。直线公理和平面公理使几百年…

详细分析ipvsadm负载均衡的命令

目录 前言1. 基本知识2. 命令参数3. 拓展 前言 LVS四层负载均衡架构详解Lvs推荐阅读&#xff1a;添加链接描述 1. 基本知识 ipvsadm 是用于管理和配置 Linux 服务器上 IP Virtual Server (IPVS) 的工具&#xff0c;是 Linux 提供的一个负载均衡模块&#xff0c;支持多种负载…

PH热榜 | 2024-11-19

DevNow 是一个精简的开源技术博客项目模版&#xff0c;支持 Vercel 一键部署&#xff0c;支持评论、搜索等功能&#xff0c;欢迎大家体验。 在线预览 1. Layer 标语&#xff1a;受大脑启发的规划器 介绍&#xff1a;体验一下这款新一代的任务和项目管理系统吧&#xff01;它…

哥德巴赫猜想渐行渐远

我现在的工作&#xff0c;表明经典分析可能出了问题&#xff0c;如此则连Vinogradov的三素数定理都不成立了&#xff0c;更别说基于L-函数方程的陈氏定理“12”了。事实上即使L-函数方程成立&#xff0c;由于我指出Siegel定理不成立&#xff0c;陈景润和张益唐的工作就不成立。…

【支持向量机(SVM)】:相关概念及API使用

文章目录 1 SVM相关概念1.1 SVM引入1.1.1 SVM思想1.1.2 SVM分类1.1.3 线性可分、线性和非线性的区分 1.2 SVM概念1.3 支持向量概念1.4 软间隔和硬间隔1.5 惩罚系数C1.6 核函数 2 SVM API使用2.1 LinearSVC API 说明2.2 鸢尾花数据集案例2.3 惩罚参数C的影响 1 SVM相关概念 1.1…

GraphRAG+Ollama实现本地部署+neo4j可视化结果

GraphRAGOllama实现本地部署neo4j可视化结果 前言一、GraphRAGOllama本地部署补充说明 二、neo4j可视化GraphRAG1.windows安装neo4j2.启动neo4j服务3.进入neo4j的webui界面4.使用neo4J可视化GraphRAG索引5.neo4j不删除旧数据&#xff0c;新建一个数据库 总结 前言 最近部署微软…

ssm142视频点播系统设计与实现+vue(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;视频点播系统设计与实现 摘 要 互联网发展到如今也近20年之久&#xff0c;视频信息一直作为互联网发展中的一个重要角色在不断更新进化。视频信息从最初的文本显示到现在集文字、视频、音频与一体&#xff0c;成为一…

Python全方位技术教程

Python全方位技术教程 引言 Python是一种强大且易于学习的编程语言&#xff0c;因其简洁的语法和丰富的库而受到广泛欢迎。无论是数据分析、机器学习、Web开发&#xff0c;还是自动化脚本&#xff0c;Python都能胜任。本文将深入探讨Python的各个方面&#xff0c;帮助读者全面…

父组件提交时让各自的子组件验证表格是否填写完整

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 父组件中有三个表格&#xff0c;表格中时输入框&#xff0c;有些输入框是必填的&#xff0c;在父组件提交时需要验证这三个表格的必填输入框中是否有没填写的。 原因分析&#xff1a; 提示&#xff1a…

基于SpringBoot+RabbitMQ完成应⽤通信

前言&#xff1a; 经过上面俩章学习&#xff0c;我们已经知道Rabbit的使用方式RabbitMQ 七种工作模式介绍_rabbitmq 工作模式-CSDN博客 RabbitMQ的工作队列在Spring Boot中实现&#xff08;详解常⽤的⼯作模式&#xff09;-CSDN博客作为⼀个消息队列,RabbitMQ也可以⽤作应⽤程…

从0-1训练自己的数据集实现火焰检测

随着工业、建筑、交通等领域的快速发展,火灾作为一种常见的灾难性事件,对生命财产安全造成了严重威胁。为了提高火灾的预警能力,减少火灾损失,火焰检测技术应运而生,成为火灾监控和预防的有效手段之一。 传统的火灾检测方法,如烟雾探测器、温度传感器等,存在响应时间慢…

计算机网络 (3)计算机网络的性能

一、计算机网络性能指标 速率&#xff1a; 速率是计算机网络中最重要的性能指标之一&#xff0c;它指的是数据的传送速率&#xff0c;也称为数据率&#xff08;Data Rate&#xff09;或比特率&#xff08;Bit Rate&#xff09;。速率的单位是比特/秒&#xff08;bit/s&#xff…

豆包MarsCode

#豆包MarsCode上新workspace# 1. 首先&#xff0c;个人所写的代码&#xff0c;会提交到gitee或者阿里的云效仓库&#xff0c;但是想在数据仓库导入的时候&#xff0c;只有github的仓库&#xff0c;希望可以加入国内的数据仓库 2. 加载不流畅&#xff0c;在使用网页版的时候&…