Bootstrap

C++时间函数的封装

今日做了一下修改:让我的库文件更加完善:
CTP程序服务器传过来的时间字符串格式是“20220511:21:27:32”。于是我封装了一个有关时间的类,在CTP程序中用起来非常方便。
真正体会到C++就是造轮子的。需要什么样的轮子就造一个,而不是从网上找一个庞大而复杂的库引入程序当中来。还是自己的“改装车”用起来得心应手。
废话少说,上代码:
CTime.h

#pragma once
#ifndef CTIME_H
#define CTIME_H

#pragma once
#include <windows.h>

// C 运行时头文件
//#include <stdlib.h>
//#include <malloc.h>
//#include <memory.h>
//#include <tchar.h>
//#include<assert.h>

#include<time.h>
#include <string>       // string

class CDateTime
{
public:
	//构造函数重载(有参)
	CDateTime(std::string strTime) :mString(strTime)
	{
		//要先对时间字符串格式进行判断
		if (!TimeStrLimit(strTime))//解析时间:"20220216:19:24:05",这是我的Ctp数据格式17位。等等
		{
			printf_s("你所提供的时间字符串格式不正确");
			return;
		}
		/*
			时间格式:"20220216:19:24:05",这是我的Ctp数据格式17位
			isalnum() 函数用来检测一个字符是否是字母或者十进制数字。
			如果仅仅检测一个字符是否是字母,可以使用 isalpha() 函数;
			如果仅仅检测一个字符是否是十进制数字,可以使用 isdigit() 函数。
			如果一个字符被 isalpha() 或者 isdigit() 检测后返回“真”,那么它被 isalnum() 检测后也一定会返回“真”。
			标准 ASCII 编码共包含了 128 个字符,不同的字符属于不同的分类,我们在 <ctype.h> 头文件中给出了详细的列表。
		*/
		//格式一,20220302:09:18:59或者20220216 19:24:05(总共有17位,第8、11、14位不是数字)Ctp的时间格式
		if (mString.size() == 17)
		{
			if (!isdigit(mString.at(8)) && !isdigit(mString.at(11)) && !isdigit(mString.at(14)))//如果第4个字符是数字
			{
				yearStr = mString.substr(0, 4);		//年份
				monthStr = mString.substr(4, 2);	//月份
				dayStr = mString.substr(6, 2);		//日期
				hourStr = mString.substr(9, 2);		//钟点
				minuteStr = mString.substr(12, 2);	//分钟
				secondStr = mString.substr(15, 2);	//秒数

				year = atoi(yearStr.c_str());		//年份数,从第0位开始复制4位,CTP的时间格式:年月日之间没有分隔符
				month = atoi(monthStr.c_str());		//月份数,从第4位开始复制2位,CTP的时间格式:年月日之间没有分隔符
				day = atoi(dayStr.c_str());			//日期数,从第6位开始复制2位,CTP的时间格式:年月日之间没有分隔符
				hour = atoi(hourStr.c_str());		//钟点数,从第9位开始复制2位
				minute = atoi(minuteStr.c_str());	//分钟数,从第12位开始复制2位
				second = atoi(secondStr.c_str());	//秒数,从第15位开始复制2位

				//weekdayStr;//暂时不做处理,用不着
			}
		}
		//格式二,"2022-02-16:19:24:05"(总共有19位,从第0位开始算,第4、7、10、13、16位不是数字)
		else if (mString.size() == 19)
		{
			if (!isdigit(mString.at(4)) && !isdigit(mString.at(7)) && !isdigit(mString.at(10)) && !isdigit(mString.at(13)) && !isdigit(mString.at(16)))//如果第4个字符是数字
			{
				yearStr = mString.substr(0, 4);		//年份,string格式,用途更广
				monthStr = mString.substr(5, 2);	//月份,string格式,用途更广
				dayStr = mString.substr(8, 2);		//日期,string格式,用途更广
				hourStr = mString.substr(11, 2);	//钟点,string格式,用途更广
				minuteStr = mString.substr(14, 2);	//分钟,string格式,用途更广
				secondStr = mString.substr(17, 2);	//秒数,string格式,用途更广
				//weekdayStr;//暂时不做处理,用不着

				year = atoi(yearStr.c_str());		//年份数,从第0位开始复制4位
				month = atoi(monthStr.c_str());		//月份数,从第5位开始复制2位
				day = atoi(dayStr.c_str());			//日期数,从第8位开始复制2位
				hour = atoi(hourStr.c_str());		//钟点数,从第11位开始复制2位
				minute = atoi(minuteStr.c_str());	//分钟数,从第14位开始复制2位
				second = atoi(secondStr.c_str());	//秒数,从第17位开始复制2位

			}
		}


		tm *_mtime= new tm;// ;
		_mtime->tm_year = year - 1900;
		_mtime->tm_mon = month - 1;
		_mtime->tm_mday = day;
		_mtime->tm_hour = hour;
		_mtime->tm_min = minute;
		_mtime->tm_sec = second;
		_mtime->tm_isdst = 0;
		mytime = mktime(_mtime); //已经减了8个时区
		//time(&mytime);//变成了当前时间
		errno_t res= localtime_s(_mtime,&mytime);  //获取当前系统时间
		weekday = _mtime->tm_wday;//一周当中的星期**
		yearday = _mtime->tm_yday;//一年当中的第***天

		delete _mtime;
		_mtime = nullptr;


	}
	//构造函数重载(无参)
	CDateTime()
	{
		time_t mtime;
		mytime=time(&mtime);

		//printf_s("看看time_t的时间格式是什么东东:%d\n", mtime);
		struct tm* info = new tm;

		localtime_s(info, &mtime);//把秒mtime转化为结构体时间info
		//printf("localtime现在是%d年 %d月%d日\n", info->tm_year + 1900, info->tm_mon, info->tm_mday);
		//printf("localtime现在是%d点 %d分\n", info->tm_hour, info->tm_min);

		year = info->tm_year + 1900;//年
		month = info->tm_mon+1;		//月
		day = info->tm_mday;		//日
		hour = info->tm_hour;		//时
		minute = info->tm_min;		//分
		second = info->tm_sec;		//秒
		weekday = info->tm_wday;	//一周当中的星期**
		yearday = info->tm_yday;	//一年当中的第***天

		delete info;//凡是new出来的,都必须delete
		info = nullptr;//逢野必空



		yearStr = std::to_string(year);		//年份,string格式,用途更广
		monthStr = std::to_string(month);	//月份,string格式,用途更广
		dayStr = std::to_string(day);		//日期,string格式,用途更广
		hourStr = std::to_string(hour);		//钟点,string格式,用途更广
		minuteStr = std::to_string(minute);	//分钟,string格式,用途更广
		secondStr = std::to_string(second);	//秒数,string格式,用途更广
		//weekdayStr;//暂时不做处理,用不着

	}
	~CDateTime()
	{
		mString.clear();
	}
	int year = 0;
	int month = 0;
	int day = 0;
	int hour = 0;
	int minute = 0;
	int second = 0;
	int weekday = 0;
	int yearday = 0;
	time_t mytime = 0;//秒数时间,即所计算的秒数时间
	std::string yearStr;
	std::string  monthStr;
	std::string  dayStr;
	std::string  hourStr;
	std::string  minuteStr;
	std::string  secondStr;
	std::string  weekdayStr;
	//由于windows下没有strptime函数,所以可以使用scanf来格式化

private:
	std::string mString;
	//解析时间:"20220216:19:24:05"
	//char strmSecond[3];		//毫秒

	//获得秒数时间,即**日(周0、周1、周2、周3、周4、周5、周6)
	int DayOfWeek()
	{
	}
	//时间字符串解析函数
	//参数:
	//std::string InputTimeStr输入的时间字符串
	//int strLengthLimit:输入的字符长度 
	bool TimeStrLimit(std::string InputTimeStr)
	{
		int iLength = InputTimeStr.size();//获得输入的时间字符串的长度
		std::string szLimitStr = std::string("0123456789:/-. ");//时间字符串里面允许存在的字符"20220216:19:24:05""20220216/19/24/05""2022-02-16-19-24-05"
		if (iLength== 17|| iLength == 19)
		{
			//判断时间字符串中是否包含非限定字符
			for (auto itr = InputTimeStr.begin(); itr != InputTimeStr.end(); ++itr)//把字符串szLimit(",0123456789")遍历一遍
			{

				//看看字符串里第itr个字符在不在限定的字符串里面
				bool IsExist = false;//找到没???
				for (auto itrLimit = szLimitStr.begin(); itrLimit != szLimitStr.end(); ++itrLimit)
				{
					if (*itr == *itrLimit)//字符*itr存在于限定字符集当中
					{
						//return;//不可以结束函数,别的字符也要检查
						IsExist = true;//找到了,当前字符*itr合规
						break;//内层循环到此结束,
					}
				}
				if (!IsExist)//*itr字符在szLimitStr里找了一圈也没有找到对应的字符,*itr字符不合格
				{
					char tmpt[2];
					tmpt[0] = *itr;
					tmpt[1] = '\0';
					MessageBoxA(NULL, tmpt, "时间字符串不合格", MB_OK);
					return false;
				}
			}
			return true;//能执行到这一步,说明输入的时间字符串是正确的
		}
		else//所给的时间字符串长度不符合要求,时间格式不正确
		{
			MessageBoxA(NULL, "所给的时间字符串长度不符合要求", "时间格式不正确", MB_OK);
			return false;
		}
	}
};
#endif // !CTIME_H



接下来,调用我的类看看效果如何:main.cpp

#include"CTime.h"
#include<stdio.h>
CDateTime ctm1("2022/05/09/21/54/38");
CDateTime ctm2;
CDateTime ctm3("1998.05.08.09.32.49");
CDateTime ctm4("1988-12-08-09-28-34");
CDateTime ctm5("1988:12:08:09:28:34");
CDateTime ctm6("20220216:19:24:05");

int main()
{

	printf_s("ctm1的时间:%d年%d月%d日%d时%d分%d秒\n", ctm1.year, ctm1.month, ctm1.day, ctm1.hour, ctm1.minute, ctm1.second);
	printf_s("ctm1的time_t格式的时间是一年当中的第%d天,星期%d\n\n",  ctm1.yearday, ctm1.weekday);

	printf_s("ctm2的时间:%d年%d月%d日%d时%d分%d秒\n", ctm2.year, ctm2.month, ctm2.day, ctm2.hour, ctm2.minute, ctm2.second);
	printf_s("ctm2的time_t格式的时间是一年当中的第%d天,星期%d\n\n",  ctm2.yearday, ctm2.weekday);

	printf_s("ctm3的时间:%d年%d月%d日%d时%d分%d秒\n", ctm3.year, ctm3.month, ctm3.day, ctm3.hour, ctm3.minute, ctm3.second);
	printf_s("ctm3的time_t格式的时间是一年当中的第%d天,星期%d\n\n",  ctm3.yearday, ctm3.weekday);

	printf_s("ctm4的时间:%d年%d月%d日%d时%d分%d秒\n", ctm4.year, ctm4.month, ctm4.day, ctm4.hour, ctm4.minute, ctm4.second);
	printf_s("ctm4的time_t格式的时间是是一年当中的第%d天,星期%d\n\n", ctm4.yearday, ctm4.weekday);

	printf_s("ctm5的时间:%d年%d月%d日%d时%d分%d秒\n", ctm5.year, ctm5.month, ctm5.day, ctm5.hour, ctm5.minute, ctm5.second);
	printf_s("ctm5的time_t格式的时间是一年当中的第%d天,星期%d\n\n", ctm5.yearday, ctm5.weekday);

	printf_s("ctm6的时间:%d年%d月%d日%d时%d分%d秒\n", ctm6.year, ctm6.month, ctm6.day, ctm6.hour, ctm6.minute, ctm6.second);
	printf_s("ctm6的time_t格式的时间是一年当中的第%d天,星期%d\n\n", ctm6.yearday, ctm6.weekday);

	printf_s("\n看看std::sting类型的计算结果\n");
	printf_s("ctm1的时间:%s年%s月%s日%s时%s分%s秒\n", ctm1.yearStr.c_str(), ctm1.monthStr.c_str(), ctm1.dayStr.c_str(), ctm1.hourStr.c_str(), ctm1.minuteStr.c_str(), ctm1.secondStr.c_str());
	printf_s("ctm2的时间:%s年%s月%s日%s时%s分%s秒\n", ctm2.yearStr.c_str(), ctm2.monthStr.c_str(), ctm2.dayStr.c_str(), ctm2.hourStr.c_str(), ctm2.minuteStr.c_str(), ctm2.secondStr.c_str());
	printf_s("ctm3的时间:%s年%s月%s日%s时%s分%s秒\n", ctm3.yearStr.c_str(), ctm3.monthStr.c_str(), ctm3.dayStr.c_str(), ctm3.hourStr.c_str(), ctm3.minuteStr.c_str(), ctm3.secondStr.c_str());
	printf_s("ctm4的时间:%s年%s月%s日%s时%s分%s秒\n", ctm4.yearStr.c_str(), ctm4.monthStr.c_str(), ctm4.dayStr.c_str(), ctm4.hourStr.c_str(), ctm4.minuteStr.c_str(), ctm4.secondStr.c_str());
	printf_s("ctm5的时间:%s年%s月%s日%s时%s分%s秒\n", ctm5.yearStr.c_str(), ctm5.monthStr.c_str(), ctm5.dayStr.c_str(), ctm5.hourStr.c_str(), ctm5.minuteStr.c_str(), ctm5.secondStr.c_str());
	printf_s("ctm6的时间:%s年%s月%s日%s时%s分%s秒\n", ctm6.yearStr.c_str(), ctm6.monthStr.c_str(), ctm6.dayStr.c_str(), ctm6.hourStr.c_str(), ctm6.minuteStr.c_str(), ctm6.secondStr.c_str());



	system("pause");
	return 0;
}

效果如下图:
在这里插入图片描述

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;