C++对输入string字符串进行格式判断并转化为time_t时间戳

C++对输入string字符串进行格式判断并转化为time_t时间戳

前言

学校实验要求输入一个时间段,在此时间段内进行查询统计。

我的思路是规定格式,让用户按照格式分别输入开始时间和结束时间,对时间格式进行判断,为有效时间后,将string字符串转化为time_t时间戳,通过时间戳比大小获得相应时间段的数据。

在格式判断方面,我最初是一大连串if条件判断,耗时耗力也冗杂易错。后来经过男票的提醒,老老实实用正则表达式判断。由于刚接触正则表达式,不够熟练。所以最后成型的格式判断是土洋结合的正则+部分条件判断。纯正则可以参考大佬链接:正则应用之一——日期正则表达式

代码

bool isTime(string str) {
    regex pattern("[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}");
    if(!regex_match(str, pattern)){
        return false;
    }

        int year = stoi(str.substr(0, 4));
        int month = stoi(str.substr(5, 2));
        int day = stoi(str.substr(8, 2));
        int minute = stoi(str.substr(11,2));
        int second = stoi(str.substr(14,2));

        if(year >= 1900 && month > 0 && month < 13 && minute < 25 && second < 61){

        switch(month){
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12: {
                if(day > 31){
                    return false;
                }
                break;
            }
            case 4:
            case 6:
            case 9:
            case 11: {
                if (day > 30) {
                    return false;
                }
                break;
            }
            default:break;
        }

        if(month == 2) {
            if (((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {
                if(day > 29) {
                    return false;
                }
            }
            else {
                if(day > 28){
                    return false;
                }
            }
        }
    }else{
        return false;
    }

    return true;
}

isTime()函数是格式判断的主体,先确定字符串为yyyy-MM-dd的正确格式,再对该字符串进行字符截取,截取出年月日时分,并进行月份日期匹配判断,以及年、时、分的有效范围判断。

time_t stringToTime(char *pTime){
    struct tm tm1;
    time_t time1;
    sscanf(pTime, "%d-%d-%d %d:%d",&tm1.tm_year, &tm1.tm_mon,
           &tm1.tm_mday , &tm1.tm_hour, &tm1.tm_min);
    tm1.tm_year -= 1900;
    tm1.tm_mon -= 1;
    tm1.tm_sec = 0;
    tm1.tm_isdst = -1;
    time1 = mktime(&tm1);
    return time1;
}

stringToTime()函数将时间有效的字符串以字符数组为媒介转化为时间戳。sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据,函数原型为int sscanf (const char *str,const char * format,…)。我一开始没得脑子想用sscanf函数的返回值来判断时间格式的有效性,可是根本办不到,其实sscanf这里就应该老老实实作为格式化数据的工具,格式判断应该交给外部去处理,它只用拿到正确的格式就好了。

bool loop(){
    string cho = "";
    while (cho != "N" && cho != "Y"&& cho != "n"&& cho != "y") {
        cout <<endl<< "是否重新输入?(y/n)";

        cin.clear();
        cin.sync();
        cin >> cho;
    }
    return cho != "N"&& cho != "n";
}

loop()函数用于用户输入错误时间,系统向用户确认是否需要再次输入。此函数也处理了用户输入"y"和"n"之外的数据,将一直循环到你老老实实输入"y"和"n"为止。

bool timeInput(long& lBeginTime, long& lEndTime){
    char aBeginTime[20] = {0};
    char aEndTime[20] = {0};
    string sBeginTime;
    string sEndTime;

    cout << "请输入查询时间段:" << endl;

    while (true) {
        cout << "开始时间:(输入格式:2019-03-21 10:59)";
        getline(cin, sBeginTime);
        if (!isTime(sBeginTime)) {
            cout << "时间格式输入错误" << endl;
            if (!loop()) {
                return false;
            }
            getchar();
        } else {
            break;
        }
    }

    while(true) {
        cout << "结束时间:(输入格式:2019-03-21 10:59)";
        getline(cin, sEndTime);
        if (!isTime(sEndTime)) {
            cout << "时间格式输入错误" << endl;
            if (!loop()) {
                return false;
            }
            getchar();
        } else {
            break;
        }
    }
    strcpy(aBeginTime, sBeginTime.c_str());
    strcpy(aEndTime, sEndTime.c_str());
    lBeginTime = stringToTime(aBeginTime);
    lEndTime = stringToTime(aEndTime);
    if(lEndTime<=lBeginTime){
        cout<<"结束时间不能小于开始时间!"<<endl;
        return false;
    }
    return true;
}

timeInput()函数用于输入开始时间和结束时间并进行判断,包括判断时间段是否有效。其中,由于cin>>无法接收用户输入的字符串中的空格,所以调用getline()函数能够接收空格,同时需要配合getchar()函数来使用,吸收回车字符。

int main() {
    long lBeginTime;
    long lEndTime;

    if(!timeInput(lBeginTime,lEndTime)){
        cout << endl << "输入时间段失败!";
    }else{
        cout << endl << "输入时间段成功!";
    }
}

输入时间段成功后,手上就已经拿到lBeginTime和lEndTime两个时间的时间戳了,后面想和什么时间进行大小比较就能比了,直接判断大小,如

if(lBeginTime < lCurrentTime && lCurrentTime < lEndTime){
	//TODO 
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值