0

I'm trying to validate a date format on on a line such as this one (01 10 2017) by creating a stream.

        if(i%5==4){ //DATE
            std::string date;
            int day;
            int month;
            int year;
            std::ostringstream oss(date);
            oss >> day;
            oss >> month;
            oss >> year;
            if (day >=0 && day <= 31){
                return true;}
            if (month >=01 && month <= 12){
                return true;}
            if (year >=1900){
                return true;}
        }

However, the code doesn't compile. What could I do to improve the validation?

Thank you

2 Answers2

2

Hope this helps.

    if(i%5==4){ //DATE
        std::string date;
        int day;
        int month;
        int year;
        std::ostringstream oss(date);
        oss << day;
        oss << month;
        oss << year;
        const int lookup_table[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
        if (!(month >= 1 && month <= 12)){
            return false;}
        if (!(day >= 1 && day <= lookup_table[month-1])){
            return false;}
        if (!(year >= 1900)){
            return false;}
        return true;
    }
iBug
  • 35,554
  • 7
  • 89
  • 134
2

What could I do to improve the validation?

Use a well-tested date/time library such as Howard Hinnant's free, open source, header-only date/time library.

bool
is_DMY(const std::string& date)
{
    std::istringstream in{date};
    date::year_month_day ymd;
    in >> date::parse("%d %m %Y", ymd);
    return !in.fail();
}

Example use:

int
main()
{
    std::cout << is_DMY("30 09 2017") << '\n';
    std::cout << is_DMY("31 09 2017") << '\n';
}

which outputs:

1
0

This demonstrates that the first test in the OP:

       if (day >=0 && day <= 31){
            return true;}

will prematurely return true for "31 09 2017". There are only 30 days in Sep.

Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577