Question

I am trying to use strptime(buf, &pattern,&result) to convert char[] containing date into tm structure.

I am using function like this:

if(strptime(buf, &pattern,&result) == NULL)
   {
      printf("\nstrptime failed\n");
...

and everything works if my variables are defined like this:

char buf[] = "26/10/2011";
char pattern[] = "%d/%m/%y";
struct tm result;

but if I change them into:

char buf[] = "2011/26/10";
char pattern[] = "%y/%d/%m";
struct tm result;

I get "strptime failed". Notice, that I have only put year in the beginning (both in buf and pattern).

Help appreciated. My final target is to convert string in this format: 2011-10-26T08:39:21

Was it helpful?

Solution

It's because the lower case %y is for the two-digit year within the century. Try changing it to uppercase %Y and it will work okay. You can see this from the following program:

#include <stdio.h>
#include <time.h>
int main (void) {
    char buf[] = "26/10/2011";
    char pattern[] = "%d/%m/%y";
    struct tm result;
    if (strptime (buf, pattern, &result) == NULL) {
        printf("strptime failed\n");
        return -1;
    }
    printf ("%d\n", 1900 + result.tm_year);
    return 0;
}

This outputs 2020, meaning that the year is being read as just the 20 portion of 2011, with the remainder being ignored. If you use upper-case %Y, it outputs the correct 2011 instead.

Code that generates the conversion error using the reversed format:

#include <stdio.h>
#include <time.h>
int main (void) {
    char buf[] = "2011/10/26";
    char pattern[] = "%y/%m/%d";
    struct tm result;
    if (strptime (buf, pattern, &result) == NULL) {
        printf("strptime failed\n");
        return -1;
    }
    printf ("%d\n", 1900 + result.tm_year);
    return 0;
}

will work fine (ie, output 2011) when you change the pattern value to "%Y/%m/%d".

OTHER TIPS

Using my own 'strptime' and 'timestamp' commands, I get:

$ strptime -T '%y/%d/%m' 2011/26/11
strptime: failed to convert <2011/26/11> using format <%y/%d/%m>
$ strptime -T '%Y/%d/%m' 2011/26/11
1322294400 = 2011/26/11
$ strptime -T '%d/%m/%y' 26/11/2011
1606377600 = 26/11/2011
$ timestamp 1322294400 1606377600
1322294400 = Sat Nov 26 00:00:00 2011
1606377600 = Thu Nov 26 00:00:00 2020
$

(Time zone here is US/Pacific, currently UTC-7.)

Note that the '%d/%m/%y' format generates a date in 2020, not in 2011.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top