I have the following code to parse a datetime string received from GPS satellites into the struct tm, and then use mktime() to get the epoch from it, the result is correct on my Debian machine, but wrong on my ESP32 with ESP-IDF, do you have any suggestion on why this is happening, is something wrong with DST or timezone stuff?
#include "rs_time.h"
time_t time_from_gnss_info_time(const char * datetime_str){
time_t epoch;
struct tm tm;
sscanf(
datetime_str,
"M-----",
&tm.tm_year,
&tm.tm_mon,
&tm.tm_mday,
&tm.tm_hour,
&tm.tm_min,
&tm.tm_sec
);
epoch = mktime(&tm); // result is '1462765068' or Mon May 9 03:37:48 2016
printf("the date and time is: %s %ld ",ctime(&epoch), time(NULL));
return epoch;
}
the value for epoch after using mktime() when the datetime_str is '20210913221332' is: 1462765068, also the ctime() representation is : Mon May 9 03:37:48 2016
CodePudding user response:
.tm_yearis years since 1900..tm_monis months since January.mktime()uses all members ofstruct tm(except for.tm_wday, .tm_yday) to form the return value. OP's code did not initialize/set.tm_isdstor others -struct tmmay have more than usual 9 members. Initialize them all.mktime()forms atime_tassumingstruct tmis a local time, not universal time which is usually what GPS provides. TZ adjustment may be needed - not yet shown.time_tdoes not certainly match along. Cast to a wide type. (time_tmay even be floating point.) and match specifiers.Add error checking.
time_t time_from_gnss_info_time(const char *datetime_str) {
// Code is likely scanning per the current daylight time setting.
// Use .tm_isdst = -1 to let mktime to determine it.
// Or use 0 for standard time or any value for daylight time.
// All other members are zeroed
// struct tm tm; // Not this
struct tm tm = {.tm_isdst = -1};
if (sscanf(datetime_str, "M-----", &tm.tm_year, &tm.tm_mon,
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
return -1;
}
// Adjust some members.
tm.tm_year -= 1900;
tm.tm_mon--;
time_t epoch = mktime(&tm);
printf("The date and time is: %s%lld\n", ctime(&epoch),
(long long) time(NULL));
return epoch;
}
int main(void) {
time_t t = time_from_gnss_info_time("20210913221332");
printf("%lld\n", (long long) t);
}
Output
The date and time is: Mon Sep 13 22:13:32 2021
1664290016
1631589212
Additional error checking possible: extra txt, spaces, signs, extreme values, ...
