DS3231 rtc program cannot run

Previously my rdc ds3231 program was running with this code, I don't know why it suddenly became a problem like this

========================================
INITIALIZING DS3231 RTC
========================================
 DS3231 detected!
 RTC has battery backup - time will persist

RTC Current Time: 00:00:00 52/83/2045

 RTC time is valid - using RTC time
   System time set from RTC: 00:00:00 52/83/2045
   Timestamp: -1463725696

========================================
AUTO NTP SYNC STARTED
========================================
Trying NTP server: pool.ntp.org
   Using timezone: UTC+7 (25200 seconds)
NTP Sync successful!
   Server: pool.ntp.org
   Time: 19:39:29 15/12/2025
NTP time saved to RTC
   (RTC overwritten from NTP)

RTC INVALID: Year out of range (2108)
RTC SUSPICIOUS: Time diff too large (1518316001 seconds)
   System: 19:40:25 15/12/2025
   RTC:    45:162:00 51/41/2108
Keeping system time (RTC probably corrupted)
RTC corrupted, resetting to system time...

code

bool initRTC() {
  Serial.println("\n========================================");
  Serial.println("INITIALIZING DS3231 RTC");
  Serial.println("========================================");

  Wire.begin();

  Wire.beginTransmission(0x68);
  Wire.endTransmission();

  if (!rtc.begin(&Wire)) {
    Serial.println(" DS3231 not found!");
    Serial.println("   - SDA -> GPIO21");
    Serial.println("   - SCL -> GPIO22");
    Serial.println("   - VCC -> 3.3V");
    Serial.println("   - GND -> GND");
    Serial.println("   - BATTERY -> CR2032 (optional)");
    Serial.println("\n Running without RTC");
    Serial.println("   Time will reset to 00:00:00 01/01/2000 on power loss");
    Serial.println("========================================\n");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      xSemaphoreGive(timeMutex);
    }

    return false;
  }

  Serial.println(" DS3231 detected!");

  if (rtc.lostPower()) {
    Serial.println(" RTC lost power - battery may be dead or missing");
    Serial.println("   Install CR2032 battery for time persistence");
  } else {
    Serial.println(" RTC has battery backup - time will persist");
  }

  DateTime rtcNow = rtc.now();

  Serial.printf("\nRTC Current Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                rtcNow.day(), rtcNow.month(), rtcNow.year());

  // ================================
  // CHECK IF RTC TIME IS VALID
  // ================================
  if (rtcNow.year() >= 2000 && rtcNow.year() <= 2100) {
    Serial.println("\n RTC time is valid - using RTC time");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      time_t rtcUnix = rtcNow.unixtime();

      setTime(rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
              rtcNow.day(), rtcNow.month(), rtcNow.year());

      timeConfig.currentTime = rtcUnix;

      Serial.printf("   System time set from RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                    rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                    rtcNow.day(), rtcNow.month(), rtcNow.year());
      Serial.printf("   Timestamp: %ld\n", timeConfig.currentTime);

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  } else {
    Serial.println("\n RTC time invalid (year out of range)");
    Serial.println("   Resetting to default time: 00:00:00 01/01/2000");

    DateTime defaultTime(2000, 1, 1, 0, 0, 0);
    rtc.adjust(defaultTime);

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      Serial.println("   System time set to 00:00:00 01/01/2000");
      Serial.printf("   Timestamp: %ld\n", timeConfig.currentTime);
      Serial.println("   RTC will maintain this until NTP sync");

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  }

  Serial.println("========================================\n");
  return true;
}

code

void ntpTask(void *parameter) {
  esp_task_wdt_add(NULL);

  while (true) {
    esp_task_wdt_reset();

    uint32_t notifyValue = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(30000));

    if (notifyValue == 0) {
      esp_task_wdt_reset();
      continue;
    }

    ntpSyncInProgress = true;
    ntpSyncCompleted = false;

    Serial.println("\n========================================");
    Serial.println("AUTO NTP SYNC STARTED");
    Serial.println("========================================");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      bool syncSuccess = false;
      int serverIndex = 0;

      while (!syncSuccess && serverIndex < NTP_SERVER_COUNT) {
        esp_task_wdt_reset();

        Serial.printf("Trying NTP server: %s\n", ntpServers[serverIndex]);

        timeClient.setPoolServerName(ntpServers[serverIndex]);
        int offsetSeconds = timezoneOffset * 3600;
        timeClient.setTimeOffset(offsetSeconds);
        Serial.printf("   Using timezone: UTC%s%d (%d seconds)\n",
                      timezoneOffset >= 0 ? "+" : "", timezoneOffset, offsetSeconds);
        timeClient.begin();

        unsigned long startTime = millis();
        bool updateResult = false;

        while (millis() - startTime < 5000) {
          updateResult = timeClient.forceUpdate();
          if (updateResult) break;

          esp_task_wdt_reset();
          vTaskDelay(pdMS_TO_TICKS(100));
        }

        if (updateResult) {
          time_t ntpTime = timeClient.getEpochTime();

          timeConfig.currentTime = ntpTime;
          setTime(timeConfig.currentTime);
          timeConfig.ntpSynced = true;
          syncSuccess = true;
          timeConfig.ntpServer = String(ntpServers[serverIndex]);

          Serial.println("NTP Sync successful!");
          Serial.printf("   Server: %s\n", ntpServers[serverIndex]);
          Serial.printf("   Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(ntpTime), minute(ntpTime), second(ntpTime),
                        day(ntpTime), month(ntpTime), year(ntpTime));

          if (rtcAvailable) {
            DateTime dt(year(ntpTime),
                        month(ntpTime),
                        day(ntpTime),
                        hour(ntpTime),
                        minute(ntpTime),
                        second(ntpTime));

            rtc.adjust(dt);

            Serial.println("NTP time saved to RTC");
            Serial.println("   (RTC overwritten from NTP)");
          }

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

          Serial.println("Post-NTP: Checking prayer times...");

          if (prayerConfig.latitude.length() > 0 && prayerConfig.longitude.length() > 0) {

            Serial.println("   City configured: " + prayerConfig.selectedCity);
            Serial.println("   Updating prayer times with correct date...");

            xSemaphoreGive(timeMutex);

            esp_task_wdt_reset();

            getPrayerTimesByCoordinates(
              prayerConfig.latitude,
              prayerConfig.longitude);

            Serial.println("Prayer times updated post-NTP sync");

            xSemaphoreTake(timeMutex, portMAX_DELAY);

          } else {
            Serial.println("No city coordinates - skipping prayer update");
            xSemaphoreGive(timeMutex);
            xSemaphoreTake(timeMutex, portMAX_DELAY);
          }

          Serial.println("========================================\n");
          break;
        }

        serverIndex++;
        esp_task_wdt_reset();
        vTaskDelay(pdMS_TO_TICKS(500));
      }

      if (!syncSuccess) {
        Serial.println("All NTP servers failed!");
        Serial.println("   Keeping current time");
        Serial.println("========================================\n");
      }

      ntpSyncInProgress = false;
      ntpSyncCompleted = syncSuccess;

      xSemaphoreGive(timeMutex);

    } else {
      Serial.println("Failed to acquire time mutex");
      Serial.println("========================================\n");

      ntpSyncInProgress = false;
      ntpSyncCompleted = false;
    }

    esp_task_wdt_reset();
  }
}

code

void rtcSyncTask(void *parameter) {
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = pdMS_TO_TICKS(60000);  // Every 1 minute

  while (true) {
    if (rtcAvailable) {
      DateTime rtcTime = rtc.now();

      if (xSemaphoreTake(timeMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
        time_t systemTime = timeConfig.currentTime;
        time_t rtcUnix = rtcTime.unixtime();

        // ========================================
        // VALIDASI KETAT
        // ========================================
        bool rtcValid = true;

        if (rtcTime.year() < 2000 || rtcTime.year() > 2100) {
          Serial.println("RTC INVALID: Year out of range (" + String(rtcTime.year()) + ")");
          rtcValid = false;
        }

        long timeDiff = abs(systemTime - rtcUnix);
        if (systemTime >= 946684800 && timeDiff > 3600) {
          Serial.printf("RTC SUSPICIOUS: Time diff too large (%ld seconds)\n", timeDiff);
          Serial.printf("   System: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(systemTime), minute(systemTime), second(systemTime),
                        day(systemTime), month(systemTime), year(systemTime));
          Serial.printf("   RTC:    %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());
          Serial.println("Keeping system time (RTC probably corrupted)");
          rtcValid = false;
        }

        // ========================================
        // Hanya update jika RTC valid DAN selisih kecil
        // ========================================
        if (rtcValid && timeDiff > 2) {
          timeConfig.currentTime = rtcUnix;
          setTime(rtcUnix);

          Serial.println("System time synced from RTC");
          Serial.printf("   RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

        } else if (!rtcValid) {
          Serial.println("RTC corrupted, resetting to system time...");

          DateTime fixedTime(
            year(systemTime),
            month(systemTime),
            day(systemTime),
            hour(systemTime),
            minute(systemTime),
            second(systemTime));

          rtc.adjust(fixedTime);
          Serial.println("RTC reset to system time");
        }

        xSemaphoreGive(timeMutex);
      }
    }

    vTaskDelayUntil(&xLastWakeTime, xFrequency);
  }
}

Try running the example code given with the library to set the clock to a current time .
Then upload your code again .
Your code doesn’t seem like the time difference between the clock and server times .
Check your cr2032 battery is ok

Run the following test program and check that RTC3231 is ok.

#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
DateTime myDT;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
byte lastReadSecond = 0;

void setup ()
{
  Serial.begin(9600);
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // rtc.adjust(DateTime(2021, 12, 31, 01, 59, 57));
  //set date-time manualy:yr,mo,dy,hr,mn,sec
}

void loop ()
{
  myDT = rtc.now();
  if (lastReadSecond != myDT.second())//wait 1-sec as long as they are equal = 1s has not gones
  {
    showTime();
  }
}

void showTime()
{
  //update to the new second
  myDT = rtc.now();
  lastReadSecond = myDT.second();
  //------------------------------
  Serial.print(myDT.year(), DEC);
  Serial.print('/');
  //-----------------------------
  Serial.print(myDT.month(), DEC);
  Serial.print('/');
  Serial.print(myDT.day(), DEC);
  Serial.print(" (");
  Serial.print(daysOfTheWeek[myDT.dayOfTheWeek()]);
  Serial.print(") ");
  //-----------------------------
  byte myHour = myDT.hour();
  if (myHour < 10)
  {
    Serial.print('0');  //show leading zero
  }
  Serial.print(myHour, DEC);
  Serial.print(':');
  //-----------------------------
  byte myMin = myDT.minute();
  if (myMin < 10)
  {
    Serial.print('0');  //show leading zero
  }
  Serial.print(myMin, DEC);
  Serial.print(':');
  //--------------------------
  byte mySec = myDT.second();
  if (mySec < 10)
  {
    Serial.print('0');  //show leading zero
  }
  Serial.print(mySec, DEC);
  //----------------------------
  Serial.println();
}

Previously my rdc ds3231 program was running with this code, I don't know why it suddenly became a problem like this

========================================
INITIALIZING DS3231 RTC
========================================
 DS3231 detected!
 RTC has battery backup - time will persist

RTC Current Time: 00:00:00 52/83/2045

 RTC time is valid - using RTC time
   System time set from RTC: 00:00:00 52/83/2045
   Timestamp: -1463725696

========================================
AUTO NTP SYNC STARTED
========================================
Trying NTP server: pool.ntp.org
   Using timezone: UTC+7 (25200 seconds)
NTP Sync successful!
   Server: pool.ntp.org
   Time: 19:39:29 15/12/2025
NTP time saved to RTC
   (RTC overwritten from NTP)

RTC INVALID: Year out of range (2108)
RTC SUSPICIOUS: Time diff too large (1518316001 seconds)
   System: 19:40:25 15/12/2025
   RTC:    45:162:00 51/41/2108
Keeping system time (RTC probably corrupted)
RTC corrupted, resetting to system time...

code

bool initRTC() {
  Serial.println("\n========================================");
  Serial.println("INITIALIZING DS3231 RTC");
  Serial.println("========================================");

  Wire.begin();

  Wire.beginTransmission(0x68);
  Wire.endTransmission();

  if (!rtc.begin(&Wire)) {
    Serial.println(" DS3231 not found!");
    Serial.println("   - SDA -> GPIO21");
    Serial.println("   - SCL -> GPIO22");
    Serial.println("   - VCC -> 3.3V");
    Serial.println("   - GND -> GND");
    Serial.println("   - BATTERY -> CR2032 (optional)");
    Serial.println("\n Running without RTC");
    Serial.println("   Time will reset to 00:00:00 01/01/2000 on power loss");
    Serial.println("========================================\n");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      xSemaphoreGive(timeMutex);
    }

    return false;
  }

  Serial.println(" DS3231 detected!");

  if (rtc.lostPower()) {
    Serial.println(" RTC lost power - battery may be dead or missing");
    Serial.println("   Install CR2032 battery for time persistence");
  } else {
    Serial.println(" RTC has battery backup - time will persist");
  }

  DateTime rtcNow = rtc.now();

  Serial.printf("\nRTC Current Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                rtcNow.day(), rtcNow.month(), rtcNow.year());

  // ================================
  // CHECK IF RTC TIME IS VALID
  // ================================
  if (rtcNow.year() >= 2000 && rtcNow.year() <= 2100) {
    Serial.println("\n RTC time is valid - using RTC time");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      time_t rtcUnix = rtcNow.unixtime();

      setTime(rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
              rtcNow.day(), rtcNow.month(), rtcNow.year());

      timeConfig.currentTime = rtcUnix;

      Serial.printf("   System time set from RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                    rtcNow.hour(), rtcNow.minute(), rtcNow.second(),
                    rtcNow.day(), rtcNow.month(), rtcNow.year());
      Serial.printf("   Timestamp: %ld\n", timeConfig.currentTime);

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  } else {
    Serial.println("\n RTC time invalid (year out of range)");
    Serial.println("   Resetting to default time: 00:00:00 01/01/2000");

    DateTime defaultTime(2000, 1, 1, 0, 0, 0);
    rtc.adjust(defaultTime);

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      setTime(0, 0, 0, 1, 1, 2000);
      time_t tempTime = now();

      if (tempTime < 946684800) {
        timeConfig.currentTime = 946684800;
      } else {
        timeConfig.currentTime = tempTime;
      }

      Serial.println("   System time set to 00:00:00 01/01/2000");
      Serial.printf("   Timestamp: %ld\n", timeConfig.currentTime);
      Serial.println("   RTC will maintain this until NTP sync");

      xSemaphoreGive(timeMutex);

      if (displayQueue != NULL) {
        DisplayUpdate update;
        update.type = DisplayUpdate::TIME_UPDATE;
        xQueueSend(displayQueue, &update, 0);
      }
    }
  }

  Serial.println("========================================\n");
  return true;
}

code

void ntpTask(void *parameter) {
  esp_task_wdt_add(NULL);

  while (true) {
    esp_task_wdt_reset();

    uint32_t notifyValue = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(30000));

    if (notifyValue == 0) {
      esp_task_wdt_reset();
      continue;
    }

    ntpSyncInProgress = true;
    ntpSyncCompleted = false;

    Serial.println("\n========================================");
    Serial.println("AUTO NTP SYNC STARTED");
    Serial.println("========================================");

    if (xSemaphoreTake(timeMutex, portMAX_DELAY) == pdTRUE) {
      bool syncSuccess = false;
      int serverIndex = 0;

      while (!syncSuccess && serverIndex < NTP_SERVER_COUNT) {
        esp_task_wdt_reset();

        Serial.printf("Trying NTP server: %s\n", ntpServers[serverIndex]);

        timeClient.setPoolServerName(ntpServers[serverIndex]);
        int offsetSeconds = timezoneOffset * 3600;
        timeClient.setTimeOffset(offsetSeconds);
        Serial.printf("   Using timezone: UTC%s%d (%d seconds)\n",
                      timezoneOffset >= 0 ? "+" : "", timezoneOffset, offsetSeconds);
        timeClient.begin();

        unsigned long startTime = millis();
        bool updateResult = false;

        while (millis() - startTime < 5000) {
          updateResult = timeClient.forceUpdate();
          if (updateResult) break;

          esp_task_wdt_reset();
          vTaskDelay(pdMS_TO_TICKS(100));
        }

        if (updateResult) {
          time_t ntpTime = timeClient.getEpochTime();

          timeConfig.currentTime = ntpTime;
          setTime(timeConfig.currentTime);
          timeConfig.ntpSynced = true;
          syncSuccess = true;
          timeConfig.ntpServer = String(ntpServers[serverIndex]);

          Serial.println("NTP Sync successful!");
          Serial.printf("   Server: %s\n", ntpServers[serverIndex]);
          Serial.printf("   Time: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(ntpTime), minute(ntpTime), second(ntpTime),
                        day(ntpTime), month(ntpTime), year(ntpTime));

          if (rtcAvailable) {
            DateTime dt(year(ntpTime),
                        month(ntpTime),
                        day(ntpTime),
                        hour(ntpTime),
                        minute(ntpTime),
                        second(ntpTime));

            rtc.adjust(dt);

            Serial.println("NTP time saved to RTC");
            Serial.println("   (RTC overwritten from NTP)");
          }

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

          Serial.println("Post-NTP: Checking prayer times...");

          if (prayerConfig.latitude.length() > 0 && prayerConfig.longitude.length() > 0) {

            Serial.println("   City configured: " + prayerConfig.selectedCity);
            Serial.println("   Updating prayer times with correct date...");

            xSemaphoreGive(timeMutex);

            esp_task_wdt_reset();

            getPrayerTimesByCoordinates(
              prayerConfig.latitude,
              prayerConfig.longitude);

            Serial.println("Prayer times updated post-NTP sync");

            xSemaphoreTake(timeMutex, portMAX_DELAY);

          } else {
            Serial.println("No city coordinates - skipping prayer update");
            xSemaphoreGive(timeMutex);
            xSemaphoreTake(timeMutex, portMAX_DELAY);
          }

          Serial.println("========================================\n");
          break;
        }

        serverIndex++;
        esp_task_wdt_reset();
        vTaskDelay(pdMS_TO_TICKS(500));
      }

      if (!syncSuccess) {
        Serial.println("All NTP servers failed!");
        Serial.println("   Keeping current time");
        Serial.println("========================================\n");
      }

      ntpSyncInProgress = false;
      ntpSyncCompleted = syncSuccess;

      xSemaphoreGive(timeMutex);

    } else {
      Serial.println("Failed to acquire time mutex");
      Serial.println("========================================\n");

      ntpSyncInProgress = false;
      ntpSyncCompleted = false;
    }

    esp_task_wdt_reset();
  }
}

code

void rtcSyncTask(void *parameter) {
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = pdMS_TO_TICKS(60000);  // Every 1 minute

  while (true) {
    if (rtcAvailable) {
      DateTime rtcTime = rtc.now();

      if (xSemaphoreTake(timeMutex, pdMS_TO_TICKS(100)) == pdTRUE) {
        time_t systemTime = timeConfig.currentTime;
        time_t rtcUnix = rtcTime.unixtime();

        // ========================================
        // VALIDASI KETAT
        // ========================================
        bool rtcValid = true;

        if (rtcTime.year() < 2000 || rtcTime.year() > 2100) {
          Serial.println("RTC INVALID: Year out of range (" + String(rtcTime.year()) + ")");
          rtcValid = false;
        }

        long timeDiff = abs(systemTime - rtcUnix);
        if (systemTime >= 946684800 && timeDiff > 3600) {
          Serial.printf("RTC SUSPICIOUS: Time diff too large (%ld seconds)\n", timeDiff);
          Serial.printf("   System: %02d:%02d:%02d %02d/%02d/%04d\n",
                        hour(systemTime), minute(systemTime), second(systemTime),
                        day(systemTime), month(systemTime), year(systemTime));
          Serial.printf("   RTC:    %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());
          Serial.println("Keeping system time (RTC probably corrupted)");
          rtcValid = false;
        }

        // ========================================
        // Hanya update jika RTC valid DAN selisih kecil
        // ========================================
        if (rtcValid && timeDiff > 2) {
          timeConfig.currentTime = rtcUnix;
          setTime(rtcUnix);

          Serial.println("System time synced from RTC");
          Serial.printf("   RTC: %02d:%02d:%02d %02d/%02d/%04d\n",
                        rtcTime.hour(), rtcTime.minute(), rtcTime.second(),
                        rtcTime.day(), rtcTime.month(), rtcTime.year());

          DisplayUpdate update;
          update.type = DisplayUpdate::TIME_UPDATE;
          xQueueSend(displayQueue, &update, 0);

        } else if (!rtcValid) {
          Serial.println("RTC corrupted, resetting to system time...");

          DateTime fixedTime(
            year(systemTime),
            month(systemTime),
            day(systemTime),
            hour(systemTime),
            minute(systemTime),
            second(systemTime));

          rtc.adjust(fixedTime);
          Serial.println("RTC reset to system time");
        }

        xSemaphoreGive(timeMutex);
      }
    }

    vTaskDelayUntil(&xLastWakeTime, xFrequency);
  }
}

this is the result

2025/12/16 (Tuesday) 05:38:00
2025/12/16 (Tuesday) 05:38:01
2025/12/16 (Tuesday) 05:38:02
2025/12/16 (Tuesday) 05:38:03
2025/12/16 (Tuesday) 05:38:04
2025/12/16 (Tuesday) 05:38:05
2025/12/16 (Tuesday) 05:38:06
2025/12/16 (Tuesday) 05:38:07
2025/12/16 (Tuesday) 05:38:08

Battery is normal, rtc.adjust doesn't work

Why is Post #4 a repeat of Post #1?

Why do you think it is not working?
What values are systemTime and rtcUnix before their subtraction?
Maybe timeDiff needs to be unsigned long so it is not negative when large