Nano 33 IoT gmtime offset

Hello everyone,
I'm experiencing an issue with time functions on my Arduino Nano 33 IoT, specifically with gmtime().
I'm trying to get the correct UTC time on my Nano 33 IoT connected to Arduino IoT Cloud, but gmtime() seems to be returning an incorrect value.

Board: Arduino Nano 33 IoT SAMD21

Libraries involved: RTCZero.h, time.h, and using ArduinoCloud.getLocalTime().

I'm fetching the epoch ArduinoCloud.getLocalTime(). I've verified this epoch using online converters, and it correctly represents the current UTC time.

However, when I pass this correct UTC epoch to gmtime(), the resulting struct tm (and the hours/minutes extracted from it) is consistently double of the hours ahead of the actual UTC time. For instance, if the actual UTC is 10:00, gmtime() (with the correct 10:00 UTC epoch) populates the tm_hour field as if it were 14:00.

My local timezone is UTC+2. The board seems to be showing UTC+4, even when using gmtime() which should ignore local timezone settings.

I've confirmed the epoch from the cloud is correct UTC.

The issue persists even when gmtime() is called directly with the correct UTC epoch, not just through other library functions.

Has anyone else experienced gmtime() on the Nano 33 IoT (or other SAMD21 boards) returning a time that is several hours ahead of the actual UTC, even when provided with a correct UTC epoch ?
Is this a known issue with the SAMD21 core's C standard library implementation of gmtime() ?

Are there any known workarounds other than manually subtracting the observed offset, or any configurations I might be missing that could cause gmtime() to behave this way ?

Any insights or suggestions would be greatly appreciated.
Thank you !

There is your clue.
Study the API.

Hi @airal.

Are you certain of that? As the name implies, ArduinoCloud.getLocalTime() returns the local time. This will only be UTC if you have configured the Thing to use that time zone. So if you are adding a +2 hours time offset to the value returned by ArduinoCloud.getLocalTime() while the Thing is configured for your UTC+2 time zone, the results you are observing are exactly as we would expect. If you want UTC, you should instead use ArduinoCloud.getInternalTime().

Do you get the expected output in Serial Monitor if you add this code to the loop function of your Thing sketch and then upload the sketch to your Nano 33 IoT?:

  static unsigned long timestamp;
  if (millis() - timestamp >= 5000) {
    timestamp = millis();

    time_t rawtime = ArduinoCloud.getLocalTime();

    if (rawtime == 0) {
      Serial.println("Time data is unavailable right now.");
    } else {
      Serial.print("ArduinoCloud.getLocalTime(): ");
      Serial.println(rawtime);

      tm *time = gmtime(&rawtime);

      Serial.print(1900 + time->tm_year);
      Serial.print("-");

      int month = time->tm_mon + 1;
      if (month < 10) {
        Serial.print("0");
      }
      Serial.print(month);

      Serial.print("-");

      if (time->tm_mday < 10) {
        Serial.print("0");
      }
      Serial.print(time->tm_mday);

      Serial.print(" ");

      if (time->tm_hour < 10) {
        Serial.print("0");
      }
      Serial.print(time->tm_hour);

      Serial.print(":");

      if (time->tm_min < 10) {
        Serial.print("0");
      }
      Serial.print(time->tm_min);

      Serial.println();
    }
  }