strptime() function in C fails to detect invalid dates. Ex: 2011-02-31 , 2011-04-31. Is there any other function or workaround to this problem
Asked
Active
Viewed 1.2k times
5
-
I am looking out for something that would give me an indication as to which part of the date is invalid. Just like how strptime() returns the pointer to the last valid character parsed. Thanks – Andy Stow Away Jul 11 '12 at 08:54
1 Answers
6
You can use mktime
to normalize your structure after using strptime
.
struct tm ltm = {0};
char buf[] = "2011-02-31";
puts(buf);
strptime(buf, "%Y-%m-%d", <m);
mktime(<m);
strftime(buf, sizeof(buf), "%Y-%m-%d", <m);
puts(buf);
The example above will produce the output below:
2011-02-31
2011-03-03
If the strings before and after mktime
do not match, then you know the input string was not a valid date.
If you need to know which field was invalid, you can save a copy of the ltm
structure before calling mktime
. Then, you can examine if the day (tm_mday
), month (tm_mon
), or year (tm_year
) was the one in the invalid format. For tm_mon
, 0
is January, and 11
is December. For tm_year
, it is the number of years since 1900
. Remember to account for leap year when validating the day of the month for February.

jxh
- 69,070
- 8
- 110
- 193
-
Hmmm... then I have to recompare and check if the date before normalize is the same as the date after normalize? Its a solution.. yes, but I was looking out for something that would give me an indication that the date is invalid. Just like how strptime() returns the pointer to the last valid character parsed – Andy Stow Away Jul 11 '12 at 08:26
-
That is one way to do it. It's easier that way than to manually dig through the `tm` structure to see if all the fields are right. – jxh Jul 11 '12 at 08:28
-
@AndyStowAway: I updated the answer with how to go about doing the validation. Regards – jxh Jul 11 '12 at 08:40
-
user315052: Hmmmm, how about we make two `tm` structures. One with the invalid date (before we normalize) and then another one after normalize. Then can we compare both the structures and see where the mismatch has occured ?? Any issues in this solution? – Andy Stow Away Jul 11 '12 at 08:48
-
@AndyStowAway: That is fine. But, I think a strcmp will tell you the same thing. Basically, if the strings are different, it was the `tm_mday` field that was wrong. So, you probably should just check that field first. – jxh Jul 11 '12 at 08:58
-
I think that the only way to make this work is to compare the two `tm` structures. Imagine the case where `char buf[] = "2011-2-28"`. `strftime()` output would give you `2011-02-28` and `strcmp` would wrongly declare the input date as invalid – lano1106 Dec 05 '17 at 06:07
-
@lano1106: There is an assumption that the input is in the same format as the output. Comparing `struct tm`s is mentioned in the last paragraph. – jxh Dec 05 '17 at 09:17
-
On the other hand if the variable is out of range e.g. for *`%M`* you have 60 it seems to be set to 0 (iirc it's not modulo but it's been a very very long day and I’m beyond done so can't check). This of course can complicate matters depending on the goal in mind. – Pryftan Oct 29 '18 at 00:15