YYYY-MM-DD date parsing strictly on Linux

POSIX defines a convenient strptime function that can be used to parse dates and times. Thus, theoretically, if I have a date of the format "YYYY-MM-DD", I should use strptime to parse it as follows:

 char myDate[] = "2012-01-01"; struct tm result; char *end = strptime(myDate, "%Y-%m-%d", &result); 

... and get it back in its canonical representation with:

 if (end != NULL) { char outDate[11]; strftime(outDate, sizeof(outDate), "%Y-%m-%d", &result); printf("%s\n", outDate); } else printf("Invalid date\n"); 

On OS X and Linux, this prints 2012-01-01. So far, so good! However, suppose the input input date is not in that format: 01-01-2012.

If I run the above code again, then in OS X I get an "Invalid date" which is expected. However, on Linux, I get 1-01-20 - January 20, 1 (yes, first year).

OS X strictly follows qualifiers, parsing a string as %Y only where a four-digit year exists. However, Linux takes up several freedoms and interprets the two digits as a year - it does not even seem to suggest that it is 2001, it considers it as year 1!

You can work around this by changing my if to something like

 if (end != NULL && *end == '\0') 

... but it seems hokey. Does anyone know if it's possible to make strptime on Linux a more strict way, and fail for %Y if the input string does not have a four-digit year?

+4
source share
2 answers

Cannot change strptime () behavior or specify length in format string. (I looked at the sources in glibc-2.3, strptime resets format modifiers and field widths, so something like "% 04Y" will not change anything).

But, as noted in the comments, there is nothing wrong with if (end != NULL && *end == '\0') . I would recommend using just that.

+2
source

I think it’s best to find the index of the first dash and use one mask or the other according to its value.

0
source

Source: https://habr.com/ru/post/1441892/


All Articles