Search code examples
clinuxgccstrptimetime.h

Why strptime c-function changes the structure?


Incomprehensible behavior of the function strptime():

#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>

double getPeriod(char * dateStart, char * dateStop) {
    struct tm tmStart, tmStop;
    time_t timeStampStart, timeStampStop;

    strptime(dateStart, "%Y-%m-%d %H:%M:%S", &tmStart);
    strptime(dateStop, "%Y-%m-%d %H:%M:%S", &tmStop);

    timeStampStart = mktime(&tmStart);
    timeStampStop = mktime(&tmStop);

    printf("%d\t%d\n", tmStart.tm_hour, tmStop.tm_hour);
}

int main()
{
    getPeriod("2016-12-05 18:14:35", "2016-12-05 18:18:34");
    return 0;
}

Output:

17  18

Why does this happen?

Compiler gcc (GCC) 6.2.1 OS Linux


Solution

  • tmStart and tmStop are not initialized, so some fields will be uninitialized when passed to mktime. Thus, the behavior is technically undefined.

    From the strptime man page (note the first two sentences):

    In principle, this function does not initialize tm but only stores the values specified. This means that tm should be initialized before the call. Details differ a bit between different UNIX systems. The glibc implementation does not touch those fields which are not explicitly specified, except that it recomputes the tm_wday and tm_yday field if any of the year, month, or day elements changed.