Simplest way of timekeeping?

AWOL:

I've done some tests with millis(), but it seems there's a noticeable drift after only a couple of hours

Could be your code is at fault.
But sadly, we can't see it.

#include <LiquidCrystal.h>

int g_iHour;
int g_iMin;
int g_iSec;
unsigned long g_uLastTick;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  
  // set up the LCD's number of columns and rows: 
  lcd.begin(16, 2);
  
  lcd.print("Simple LCD Clock");
  
  g_iHour = 0;
  g_iMin = 0;
  g_iSec = 0;
  
  g_uLastTick = millis();
}

void loop()
{
  // compose a string of the current time, then print it ... 
  char text[20];
  sprintf(text, "%02d:%02d:%02d", g_iHour, g_iMin, g_iSec);
  lcd.setCursor(4, 1);
  lcd.print(text);
  // (note that this is quite wasteful - we only need to update the screen every second,
  // or when a button is pressed)

  // has it been more than a second since the last update?   
  if (millis() >= (g_uLastTick + 1000))
  {
    // yes
    g_uLastTick += 1000;
    
    g_iSec++;
    if (g_iSec > 59)
    {
      g_iSec = 0;
      g_iMin++;
      if (g_iMin > 59)
      {
        g_iMin = 0;
        g_iHour++;
        if (g_iHour > 23)
        {
          g_iHour = 0;
        }
      }
    }
  }
}