Home > Enterprise >  localtime() doesn't return the correct value
localtime() doesn't return the correct value

Time:11-02

I have a problem with localtime(). The scope is to transform my own struct tbDate to struct tm. Since the simple assignment doesn't fill the follow arguments:

tmp->tm_wday;
tmp->tm_yday;
tmp->tm_year;

that I need, since I have my own implementation of strftime() So, I fill a struct tm with my own data, I call mktime() to get the secunds, than I call localtime() to get a struct tm filled, and than I fill my struct tm.

int tbDate_to_tm(tbDate *date,struct tm *syst)
{
    time_t t;

    struct tm *tmp;
    syst->tm_hour=0;
    syst->tm_min=0;
    syst->tm_sec=0;
    syst->tm_year=date->year-1900;
    syst->tm_mon=date->month-1;
    syst->tm_mday=date->day;
    
    t=mktime(syst);
    tmp=localtime(&t);
    
    syst->tm_hour=tmp->tm_hour;
    syst->tm_isdst=tmp->tm_isdst;
    syst->tm_mday=tmp->tm_mday;
    syst->tm_min=tmp->tm_min;
    syst->tm_mon=tmp->tm_mon;
    syst->tm_sec=tmp->tm_sec;
    syst->tm_wday=tmp->tm_wday;
    syst->tm_yday=tmp->tm_yday;
    syst->tm_year=tmp->tm_year;


    return 1;
}

The problem is that returns the date of the day before, rather than the correct date. The system is Windows, and the compiler mingw. Someone can notice something wrong? Example:

date->year=2022;
date->month=11;
date->day=1;
//these settings returns a time_t t
t=1667253600;
//after I call localtime()
tmp->tm_hour=23;
tmp->tm_isdst=0;
tmp->tm_mday=31;
tmp->tm_min=0;
tmp->tm_mon=9;
tmp->tm_sec=0;
tmp->tm_wday=1;
tmp->tm_yday=303;
tmp->tm_year=122;

rather than:

tmp->tm_hour=0;
tmp->tm_isdst=0;
tmp->tm_mday=1;
tmp->tm_min=0;
tmp->tm_mon=10;
tmp->tm_sec=0;
tmp->tm_wday=2;
tmp->tm_yday=304;
tmp->tm_year=122;

CodePudding user response:

You have overwritten members of *syst passed except tm_isdst.

I suggest you add one of these lines:

syst->tm_isdst = -1;
syst->tm_isdst = 0;
syst->tm_isdst = 1;

depending on your need. The MS man page for mktime says

When specifying a tm structure time, set the tm_isdst field to:

  • Zero (0) to indicate that standard time is in effect.
  • A value greater than 0 to indicate that daylight saving time is in effect.
  • A value less than zero to have the C run-time library code compute whether standard time or daylight saving time is in effect.

CodePudding user response:

Weather Vane solved, I put syst->tm_isdst=-1, and now it works:

int tbDate_to_tm(tbDate *date,struct tm *syst)
{
    time_t t;

    struct tm *tmp;
    syst->tm_hour=0;
    syst->tm_min=0;
    syst->tm_sec=0;
    syst->tm_year=date->year-1900;
    syst->tm_mon=date->month-1;
    syst->tm_mday=date->day;
    syst->tm_isdst=-1;             // added this

    t=mktime(syst);
    tmp=localtime(&t);
    
    syst->tm_hour=tmp->tm_hour;
    syst->tm_isdst=tmp->tm_isdst;
    syst->tm_mday=tmp->tm_mday;
    syst->tm_min=tmp->tm_min;
    syst->tm_mon=tmp->tm_mon;
    syst->tm_sec=tmp->tm_sec;
    syst->tm_wday=tmp->tm_wday;
    syst->tm_yday=tmp->tm_yday;
    syst->tm_year=tmp->tm_year;


    return 1;
}
  • Related