Home > Software engineering >  How to parse date string which is formed by the CRT function?
How to parse date string which is formed by the CRT function?

Time:10-27

I'm working on a Windows-driven C project now. And there is a function which composes a file names with date portion in them. It uses the wcsftime C runtime library function to format the date portion with the "%x" formating code. This code corresponds to the

%x Date representation for the locale

as the documentation says.

Now, I need to check which files match to some dates-range. So, I need to parse this date portion of the file name back to the date and perform the comparing. But, I'm in trouble: how to do this? I didn't find any CRT function which can do the work. Furthermore, it could be much more better for me to get the formating string alike the "dd-mm-yyyy" for the current locale in order to parse this string. But I didn't find any way how to do this.

I pay your attention, that it's about the CRT functions. Its locale differs from the locale used by the GetLocaleInfo, for example.

CodePudding user response:

The big question is, if you know the locale with which the date in the string was created.

If you are on the same machine then you can use the time_get function described here.

With that you can get the order of the day, month, year in the date. Having that you can then first build a std::regex to extract the digits and then assign the digits into the corresponding date segments.

A regex could look like R"(\d{1,4}[.\/,;]\d{1,4}[.\/,;]\d{1,4})" which will match 3 digit groups separated by some typical date separators.

Then, with the know how of the date order, you can extract day, month and year from a string.

Some example code:

#include <iostream>
#include <locale>
#include <string>
#include <regex>
#include <iomanip>

// Example for year/month/day formated string
std::string fileName{"file7_234x2021/5/23abc.txt"};
std::regex re{R"((\d )[\.\\\/\,\;](\d{1,4})[\.\\\/\,\;](\d{1,4}))"};


int main() {
    
    std::smatch sm{};
    
    if (std::regex_search(fileName,sm,re)) {
        
            int year = std::stoi(sm[1]);
            int month = std::stoi(sm[2]);
            int day = std::stoi(sm[3]);
            
            std::cout << std::right << std::setfill('0') << std::setw(2) << day << '-' << std::setw(2) << month 
            << '-'<< std::setw(4) << year << '\n';
    }
}

If you do not know the date order, then you may have a big problem and can only find out with some heuristic methods what is what.

E.g.

  • Numbers above 31 are years
  • Numbers above 12 are days (or years)

But, somehow error prone . . .

CodePudding user response:

One easy solution is to go forward : Generate a filename using the same pattern, but for a test date of 2001-02-03. The result will tell you the order of year,month and day.

  • Related