The following snippet code is from rtc.c
in busybox-1.22.1
.
In my case the utc
is always 0, so this function is just doing a conversion from struct tm
to time_t
.
time_t FAST_FUNC rtc_tm2time(struct tm *ptm, int utc)
{
//fprintf(stdout, "ptm->tm_hour: %d\n", ptm->tm_hour);
char *oldtz = oldtz; /* for compiler */
time_t t;
if (utc) {
oldtz = getenv("TZ");
putenv((char*)"TZ=UTC0");
tzset();
}
t = mktime(ptm); //problem here
//struct tm* temp = localtime(&t);
//fprintf(stdout, "temp->tm_hour: %d\n", temp->tm_hour);
if (utc) {
unsetenv("TZ");
if (oldtz)
{
putenv(oldtz - 3);
}
tzset();
}
return t;
}
Also, there is a file /etc/TZ
displaying timezone and DST information.
~ # cat /etc/TZ
LMT0:00LMT-1:00,M8.5.1/10,M12.5.1/10
Then, I set system time to 2021/8/30, 9:59:30 (30 seconds earlier than DST start date), and sync to hwclock.
date -s 2021.08.30-09:59:30 >/dev/null 2>/dev/null //set system time
hwclock -w //sync RTC to system time
Entering hwclock continuously while observing the output on CLI.
~ # hwclock
ptm->tm_hour : 9
temp->tm_hour : 9
Mon Aug 30 09:59:58 2021 0.000000 seconds
~ # hwclock
ptm->tm_hour : 10
temp->tm_hour : 11 //why not 10?
Mon Aug 30 11:00:00 2021 0.000000 seconds
Why the return value from mktime
is added by 1 when entering DST? Shouldn't it be affected by DST?
According to the
mktime()
man pages,mktime()
is allowed to update thetm_isdst
value. The starting value may cause themktime()
algorithm to branch differently:and then update the value of
tm_isdst
accordingly:In other words, I'd check the
tm_isdst
value before and after themktime()
call.One way I've dealt with this in the past is to
mktime()
with a known value oftm_isdst
(e.g. zero or one)localtime()
on the returned time_t value, then checktm_isdst
on the struct tm pointerlocaltime()
returns.tm_isdst
has been changed from the prior known value, change the original struct tm to use the newtm_isdt
value then callmktime()
again with it before trusting the time_t it returns.It's definitely less efficient but it's possible to know when the DST change occurs by expecting it and checking for it.
Another option would be to set
tm_isdst
to -1 before callingmktime()
and trusting its lookup of timezone and settm_isdst
appropriately.