Timer inaccuracy when not using delay()

I’m just getting started with Arduino, so after working through some of the basic examples, I wanted to write some code that would display on an lcd screen a count of mm:ss since arduino start up.

The code I came up with is:

#include<LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 8, 7, 6, 5);

unsigned long minutes;
unsigned long seconds;
unsigned long currentTime;

unsigned long loopStartTime;
unsigned long loopEndTime = -1000;
unsigned long refreshInterval = 1000;


void getTime()
{
  currentTime = millis();
  minutes = currentTime / 60000;
  seconds = (currentTime % 60000) / 1000;
}


void setup()
{
  lcd.begin(16, 2);               
}

void loop()
{ 
  loopStartTime = millis();
  if (loopStartTime - loopEndTime >= refreshInterval)
      {
        loopEndTime = loopStartTime;
        getTime();
        lcd.setCursor(12, 1);
        lcd.print(minutes);
        lcd.print(":");
        if (seconds < 10)
        {
          lcd.print("0");
          lcd.print(seconds);
        }
        else
        {
          lcd.print(seconds);
        }
      }
}

The issue I’m finding is that compared to a stopwatch the arduino takes 00:15 to register 00:10. If I add a short delay at the end of the loop (say 100ms) it fixes the problem and the Arduino keeps time, but I want to avoid using a delay so I can monitor for button presses etc.

Could anyone advise why adding a delay is helping the code keep accuracy?

Kind Regards

  seconds = (currentTime % 60000) / 1000;

these are integer division operations

why don't you try

seconds = (currentTime / 1000) % 60;

Also, the set up() function and what happens prior to setup() takes a few seconds. Do not start your stopwatch when you apply power.