TinyGSM
TinyGSM copied to clipboard
getNetworkTime returns 1939 datetime at rare occations
[X ] I have read the Troubleshooting section of the ReadMe
What type of issues is this?
[ ] Request to support a new module [ ] Bug or problem compiling the library [ X ] Bug or issue with library functionality (ie, sending data over TCP/IP) [ ] Question or request for help
What are you working with?
Modem: SIMCOM 7080G Main processor board: ESP32 TinyGSM version: 11.1
Scenario, steps to reproduce
I do timesynchronization like this:
int year3 = 0;
int month3 = 0;
int day3 = 0;
int hour3 = 0;
int min3 = 0;
int sec3 = 0;
float timezone = 0;
if (modem.getNetworkTime(&year3, &month3, &day3, &hour3, &min3, &sec3,&timezone))
{
DateTime currentTime = DateTime(year3, month3, day3, hour3, min3, sec3);
DebugService::Information("Timezone", String(timezone));
return currentTime.unixtime() - long(timezone * 3600);
}
return 0;
Expected result
I expect to get the current time adjusted for timezone
Actual result
On rare occations (I have 30+ devices now running 24/7 and this has happend 3 times that I have witnessed) I get a datetime that tells that the TimeZone is 0 (Should be 1) and that the year is 1939. I do timesynchronization every minute and when this happens it is from startup and then every timesync until the modem is restarted. I have only have this happend once on a device that I was connected to and could watch the print out from the device.
Debug and AT command log
I have not been able to reproduce this in a debug environment, it just happends rarely and random.
Does anyone have any idea where this can originate from? Is it my code, the modem, the network or TinyGSM library?
Not really a bug, more characteristic of mobile network.
Try this:
I use it to re sync the ESP32 RTC timer once a day.
I found some network operators are a but slow to give time so I try every few minutes until successful. But don't call this in rapid succession, if you don't get it straight away, wait several seconds before trying again otherwise the ESP could get upset and reset or the network cell will block you for a while.
I'm using SIM7600 and SIM70xx
int getGSMTIME()
{
if (ModemDetected) {
//Serial.printf("GSM Time: %s\n", modem.getGSMDateTime(DATE_FULL).c_str());
int GSMyear = 0;
int GSMmonth = 0;
int GSMdate = 0;
int GSMhours = 0;
int GSMminutes = 0;
int GSMseconds = 0;
float GSMtimezone = 0;
time_t GSMUTCtime = 0;
if (modem.getNetworkTime(&GSMyear, &GSMmonth, &GSMdate, &GSMhours, &GSMminutes, &GSMseconds, &GSMtimezone))
{
struct tm s;
s.tm_sec = (GSMseconds);
s.tm_min = (GSMminutes);
s.tm_hour = (GSMhours);
s.tm_mday = (GSMdate);
s.tm_mon = (GSMmonth - 1);
s.tm_year = (GSMyear - 1900);
GSMUTCtime = mktime(&s);
if (DEBUG) {
Serial.printf("GSM Time: %s", ctime(&GSMUTCtime));
}
if (setSystemTime) { // set system time if requested
if (GSMUTCtime > 1615155060) { // check for valid time, not 1939!
setenv("TZ", "CET-0CET-0,M3.5.0/02:00:00,M10.5.0/03:00:00", 1);
tzset();
struct timeval tv;
memset(&tv, 0, sizeof(struct timeval));
tv.tv_sec = GSMUTCtime;
settimeofday(&tv, NULL);
setSystemTime = 0;
}
return 1;
}
}
return 0;
}
}
To work with DST, we have to do a mix between both code and install the time with UTC0 and then switched to the wanted TZ.
example:
struct tm t = {0, 0, 0, 0, 0, 0, 0, 0, 0};
float timezone = 0;
if (_timeState == ModemTimeState::MODEM_TIME_SYNCING && !_modem.getGSMDateTime(TinyGSMDateTimeFormat::DATE_FULL).startsWith("80/01/06") && _modem.getNetworkTime(&t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec, &timezone)) {
// +CCLK: "24/04/02,13:39:57+08 (dst, gmt+1, so 11:39 gmt)
t.tm_year -= 1900;
t.tm_mon -= 1;
Mycila::Logger.debug(TAG, "t.tm_year: %d", t.tm_year);
Mycila::Logger.debug(TAG, "t.tm_mon: %d", t.tm_mon);
Mycila::Logger.debug(TAG, "t.tm_mday: %d", t.tm_mday);
Mycila::Logger.debug(TAG, "t.tm_hour: %d", t.tm_hour);
Mycila::Logger.debug(TAG, "t.tm_min: %d", t.tm_min);
Mycila::Logger.debug(TAG, "t.tm_sec: %d", t.tm_sec);
// unix time
struct timeval now = {mktime(&t) - static_cast<int>(timezone * 3600.0), 0};
Mycila::Logger.debug(TAG, "now.tv_sec: %d", now.tv_sec);
// install the time
setenv("TZ", "UTC0", 1);
tzset();
settimeofday(&now, nullptr);
// change timezone
setenv("TZ", _timeZoneInfo.c_str(), 1);
tzset();
Mycila::Logger.info(TAG, "getLocalStr(): %s", Mycila::Time::getLocalStr().c_str());
Mycila::Logger.info(TAG, "getISO8601Str(): %s", Mycila::Time::getISO8601Str().c_str());
Mycila::Logger.info(TAG, "getUnixTime(): %d", Mycila::Time::getUnixTime());
if (!Mycila::Time::getLocalStr().isEmpty()) {
_timeState = ModemTimeState::MODEM_TIME_SYNCED;
_state = MODEM_READY;
}
}
output:
[0;36mD 12266 modemTask (1) MODEM >> AT+CCLK?[0m
[0;36mD 12272 modemTask (1) MODEM << [0m
[0;36mD 12273 modemTask (1) MODEM << +CCLK: "24/04/02,15:19:20+08"[0m
[0;36mD 12274 modemTask (1) MODEM << [0m
[0;36mD 12275 modemTask (1) MODEM << OK[0m
[0;36mD 12275 modemTask (1) MODEM t.tm_year: 124[0m
[0;36mD 12276 modemTask (1) MODEM t.tm_mon: 3[0m
[0;36mD 12277 modemTask (1) MODEM t.tm_mday: 2[0m
[0;36mD 12277 modemTask (1) MODEM t.tm_hour: 15[0m
[0;36mD 12277 modemTask (1) MODEM t.tm_min: 19[0m
[0;36mD 12277 modemTask (1) MODEM t.tm_sec: 20[0m
[0;36mD 12277 modemTask (1) MODEM now.tv_sec: 1712063960[0m
[0;32mI 12278 modemTask (1) MODEM getLocalStr(): 2024-04-02 15:19:20[0m
[0;32mI 12279 modemTask (1) MODEM getISO8601Str(): 2024-04-02T13:19:20Z[0m
[0;32mI 12281 modemTask (1) MODEM getUnixTime(): 1712063960[0m
We found GSM time would vary between site locations and operators. Some would be UTC0, others would be local time of the tower location. Gave up and used GPS as that's always UTC0 everywhere.
We found GSM time would vary between site locations and operators
I just ran into this issue 😒