You don't say what board is being used but most Unos, etc., use a ceramic resonator for the system clock, which will typically have a frequency tolerance on the order of ±0.5%. Changing to a crystal (say, ±20ppm) might be simplest, but if you're not in a position to do that, then I'd try a DS1307 RTC. DS1307 breakout boards can be had for under $10, some will plug directly into the headers on an Arduino Uno.Lately I've been experimenting with running an ATmega328P on the internal oscillator, and connecting a 32.768kHz crystal which acts as a clock source for Timer/Counter2. A simple RTC can then be implemented in software. Fairly straightforward, keeps decent time.

unsigned long currentmillis = 0;unsigned long previousmillis = 0;unsigned long interval = 10000;byte ones_seconds = 0;byte prior_seconds = 0;byte tens_seconds = 0;byte ones_minutes = 0;byte tens_minutes = 0;byte tenths = 0;byte hundredths= 0;void setup(){Serial.begin(57600);}void loop(){ currentmillis = micros(); // read the time. while (currentmillis - previousmillis >= interval) // 10 milliseconds have gone by { hundredths = hundredths +1; if (hundredths == 10){ hundredths = 0; tenths = tenths +1; } if (tenths == 10){ tenths = 0; ones_seconds = ones_seconds +1; } if (ones_seconds == 10){ ones_seconds = 0; tens_seconds = tens_seconds +1; } if (tens_seconds == 6){ tens_seconds = 0; ones_minutes = ones_minutes +1; } if (ones_minutes == 10){ ones_minutes = 0; tens_minutes = tens_minutes +1; } if (tens_minutes == 6){ tens_minutes = 0; } previousmillis = previousmillis + interval; // save the time for the next comparison } // counters are all updated now,if (prior_seconds != ones_seconds){ Serial.print (tens_minutes, DEC); Serial.print (" "); Serial.print (ones_minutes, DEC); Serial.print (" : "); Serial.print (tens_seconds, DEC); Serial.print (" "); Serial.println (ones_seconds, DEC);prior_seconds = ones_seconds;}} // end void loop