skip to Main Content

I’m not programming very often; I may have skipped something important but…
I expect the following code to write 31st October between 30th October and the 1st November.

My output skips the 31st.

Is it a bug? Do I misuse these functions?
I suppose I did something wrong, as I found no comment about such an existing bug.

(Using Ubuntu 24.04.1)

PS: I found my newbie myitake right before pushing "send." Publishing to help other newbies like me. I was expecting January to be indexed as the month 1 but it is month 0.

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

int main(int argc, char **argv)
{
    
    struct tm * NewDate;
    
    struct tm myDate;
    myDate.tm_mday = 30;
    myDate.tm_mon = 10;  
    myDate.tm_year = 2024;   // Date == April 6, 2014
    myDate.tm_hour = 23;
    myDate.tm_min = 59;
    myDate.tm_sec = 59;  
    
    time_t TimeStamp;
        
        
    while ( myDate.tm_min > 50 || myDate.tm_min < 5 )
    {
        printf( " %d/%d/%d_%02d:%02d n", myDate.tm_mday, myDate.tm_mon, myDate.tm_year, myDate.tm_hour, myDate.tm_min );
        
        TimeStamp = mktime ( &myDate );
        
        TimeStamp +=100;
        
        NewDate = localtime ( &TimeStamp );
        
        myDate = *NewDate;
    }
    return 0;
}

Result:

:~/Essai$ gcc bug.c 
xx@xx:~/Essai$ ./a.out 
 30/10/2024_23:59 
 1/11/2024_00:01 
 1/11/2024_00:03 
 1/11/2024_00:04 

Expecting:

 30/10/2024_23:59 
 31/10/2024_00:01 
 31/10/2024_00:03 
 31/10/2024_00:04

2

Answers


  1. The range of tm_mon is between 0-11 not 1-12. Month 10 is then November which only has 30 days, so the output is correct.

    Using strftime() you can see that this is correct:

    char buffer[255];
    if (strftime(buffer, sizeof buffer, "%A %c", &myDate))
       printf("%sn", buffer);
    

    Reference:
    struct tm

    Login or Signup to reply.
  2. Incorrect initial use of struct tm

    Code has at least these problems:

    struct tm myDate;
    myDate.tm_mday = 30;
    myDate.tm_mon = 10;  
    myDate.tm_year = 2024;   // Date == April 6, 2014
    myDate.tm_hour = 23;
    myDate.tm_min = 59;
    myDate.tm_sec = 59;  
    

    .tm_mon is the months since January. So for October, use myDate.tm_mon = 10 - 1;

    .tm_year is the years since 1900. So for 2024, use myDate.tm_year = 2024 - 1900;

    .tm_isdst is not set. Use 1 for daylight time, 0 for standard time and -1 if unsure.*1

    Incomplete initialization. struct tm has at least 7 members that need initialization. Code fails to assign at least .tm_isdst. There may be more.

    // struct tm myDate
    struct tm myDate = { 0 };  // All members are set to 0.
    

    Rather than assign later, initialize at object definition time.

    struct tm myDate = { //
        .tm_mday = 30, .tm_mon = 10 - 1, .tm_year = 2024 - 1900, //
        .tm_hour = 23, .tm_min = 59, .tm_sec = 59, //
        .tm_isdst = -1 };
        // All other members initialized to zero.
    

    *1 Interestingly for me, today is the longest day of the year: 25 hours. Time goes, in hour steps: 12:00 AM DST, 1:00 AM DST, 2:00 AM DST, 2:00 AM Std, 3:00 AM Std, 4:00 AM Std, … 23:00 PM Std,

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search