user10530006
user10530006

Reputation: 11

weird mktime behavior in standard c

With follow code, the strptime output is correct but mktime is completely off, can someone help me out here?

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

int main(void) 
{
    int ddate;
    double dt;
    char dstr1[20],dstr2[20];
    time_t s1,s2;
    struct tm d1,d2;

    strptime("04/06/2015","%m/%d/%Y",&d1); 
    strptime("08/06/2015","%m/%d/%Y",&d2);
    strftime(dstr1,20,"%Y-%m-%d",&d1);
    strftime(dstr2,20,"%Y-%m-%d",&d2); 
    printf("%s,%s\n",dstr1,dstr2);
    s1=mktime(&d1);
    s2=mktime(&d2);
    printf(ctime(&s1));
    printf(ctime(&s2));
    return(0);
}
=== output ====
2015-04-06,2015-08-06
Mon Apr  6 01:51:31 2015
Sun Jan 14 07:16:48 113900

Upvotes: 1

Views: 307

Answers (2)

The C11 description for mktime is

Description

  1. The mktime function converts the broken-down time, expressed as local time, in the structure pointed to by timeptr into a calendar time value with the same encoding as that of the values returned by the time function. The original values of the tm_wday and tm_yday components of the structure are ignored, and the original values of the other components are not restricted to the ranges indicated above. 320) On successful completion, the values of the tm_wday and tm_yday components of the structure are set appropriately, and the other components are set to represent the specified calendar time, but with their values forced to the ranges indicated above; the final value of tm_mday is not set until tm_mon and tm_year are determined.

(emphasis mine)


The garbage in d1 is the reason. I wrote a simplified program:

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

int main(void) {
    time_t s1;
    struct tm d1;

    strptime("04/06/2015","%m/%d/%Y",&d1); 
    printf("%02d:%02d:%02d\n", d1.tm_hour, d1.tm_min, d1.tm_sec);
    s1=mktime(&d1);
    puts(ctime(&s1));
    return(0);
}

The output is (for example)

910751933:01:00
Thu May  8 05:00:01 105913

I.e. it is Friday October 19 2018 at 910751933 hours 1 minutes and 0 seconds.

Unlike mktime, strftime only uses those fields of the broken-down structure that are required by the format.

Upvotes: 0

Chris Turner
Chris Turner

Reputation: 8142

It's because d1 and d2 contain garbage before you call strptime and it is only setting the year, month and day of the struct tm. So mktime is dealing with the random values in the other fields as best it can.

Add in a call to memset or use some other means to clear the content of the two variables and the code works as expected.

#define _XOPEN_SOURCE
#include <stdio.h>
#include <time.h>
#include <string.h>
int main () 

    {
    int ddate;
    double dt;
    char dstr1[20],dstr2[20];
    time_t s1,s2;
    struct tm d1,d2;

    memset(&d1,0,sizeof(d1));
    memset(&d2,0,sizeof(d2));
    strptime("04/06/2015","%m/%d/%Y",&d1); 
    strptime("08/06/2015","%m/%d/%Y",&d2);
    strftime(dstr1,20,"%Y-%m-%d",&d1);
    strftime(dstr2,20,"%Y-%m-%d",&d2); 
    printf("%s,%s\n",dstr1,dstr2);
    s1=mktime(&d1);
    s2=mktime(&d2);
    printf("%s",ctime(&s1));
    printf("%s",ctime(&s2));
    return(0);
}

Upvotes: 4

Related Questions