如何计算以不同格式输入的日期?

时间:2018-11-09 09:10:15

标签: c++ date substr

我有一个程序,需要读取输入的日期。如果输入日期D / MM / YYYY,则我可以正确读取日期。当日期输入为DD / MM / YYYY时,它会错误地读取,因为substr不能算出其中有两位数字的日期。

因此可以使用4种不同的正确方式输入日期:

D / M / YYYY

DD / MM / YYYY

D / MM / YYYY

DD / M / YYYY

此外,如果输入了不正确的日期/月份(例如100/4/2018),则会妨碍正确读取字符串的其余部分。年和月。

通过我自己的测试,我进行了一个for循环,查找第一个“ /”,然后读取它之前的内容,但这没用。

如何解释输入日期的这些不同方式?

.cma

3 个答案:

答案 0 :(得分:3)

如果替换'/',则可以仅使用istringstream进行一些简单的解析。像这样:

std::replace( date.begin(), date.end(), '/', ' ');

std::istringstream stream(date);

stream >> day_;
stream >> month_;
stream >> year_;

答案 1 :(得分:1)

使用std::string::substr拆分为令牌。这是一个简单的示例,足以让您入门:

#include <iostream>
#include <string>

int main () {
    std::string s = "09/09/2001";
    std::string delimiter = "/";

    size_t pos = 0;
    std::string token;
    int i = 0;
    while ((pos = s.find(delimiter)) != std::string::npos) {
        token = s.substr(0, pos);
        !i++ ? std::cout << "Day: " << token << std::endl : std::cout << "Month: " << token << std::endl;
        s.erase(0, pos + delimiter.length());
    }
    std::cout << "Year: " << s << std::endl;
    return 0;
}

输出:

Day: 09
Month: 09
Year: 2001

我检查了您要求的所有四个输入,并且可以正常工作。

PS:您可能希望以数字形式使用这些令牌,因此请阅读How can I convert a std::string to int?

答案 2 :(得分:0)

有多种方法可以从日期格式中提取\解析日期和时间,这就是我要做的事情:

#include <tuple>
#include <sstream>

#define IS_LEAP_YEAR(year) ((year) % 4 == 0 && (year) % 100 != 0 || (year) % 100 == 0 && (year) % 400 == 0 || (year) % 400 == 0)

std::tuple<int, int, int> GiveDateFromFormat(std::string const& format, char const delimiter = '\\')
{
    std::stringstream ss(format);
    std::string date, month, year;
    std::getline(ss, date, delimiter);
    std::getline(ss, month, delimiter);
    std::getline(ss, year, delimiter);
    auto date_num = std::stoi(date), month_num = std::stoi(month), year_num = std::stoi(year);
    if (month_num > 12 || month_num < 1 || date_num >(month_num % 2 == 0 && month_num != 2 ? 30 : 31) ||
        date_num > (IS_LEAP_YEAR(year_num) ? 29 : 28) && month_num == 2)
        throw std::invalid_argument("Date does not exist!");
    return std::make_tuple(date_num, month_num, year_num);
}
  

请注意,日期检查仅用于确定日期,并非必需...

大大缩短了,甚至可以是:

std::tuple<int, int, int> GiveDateFromFormat(std::string const& format, char const delimiter = '\\')
{
    std::stringstream ss(format);
    std::string date, month, year;
    std::getline(ss, date, delimiter);
    std::getline(ss, month, delimiter);
    std::getline(ss, year, delimiter);
    return std::make_tuple(std::stoi(date), std::stoi(month), std::stoi(year));
}

用法:

int main()
{
    auto date_time = GiveDateFromFormat("29\\2\\2016");
    std::cout << "Date: " << std::get<0>(date_time) << std::endl
              << "Month: " << std::get<1>(date_time) << std::endl
              << "Year: " << std::get<2>(date_time) << std::endl;
    return 0;
}

输出:

  

日期:29
  月:2
  年:2016