TinyGSM icon indicating copy to clipboard operation
TinyGSM copied to clipboard

getNetworkTime returns 1939 datetime at rare occations

Open dlyckelid opened this issue 3 years ago • 5 comments

[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?

dlyckelid avatar Dec 06 '21 09:12 dlyckelid

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;
  }
}

star297 avatar Dec 06 '21 16:12 star297

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

mathieucarbou avatar Apr 02 '24 13:04 mathieucarbou

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.

star297 avatar Apr 02 '24 13:04 star297

We found GSM time would vary between site locations and operators

I just ran into this issue 😒

mathieucarbou avatar Apr 03 '24 21:04 mathieucarbou