今日做了一下修改:让我的库文件更加完善:
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;
}
效果如下图: