Попробую просуммировавть свои мысли. U -- число сек. от старта программы, R -- текущее реальное время (в секундах) полученное от какого-либо источника, B -- время (реальное) момента запуска, S -- время последней синхронизации от момента пуска программы, D -- ошибка накапливаемая за секунду, тактов таймера,  Ts -- тактов таймера в секунду.
Изначально U:=0, B:=0, S:=0, D:=0. Таймер программируется на срабатывание раз в T:=Tps+D единиц счёта. В момент срабатывания вычисляется U:=U+1, таймер программируется на T:=T+Tps+D (таким образом тут нет накопления ошибки).
В какой-то момент времени происходит синхронизация (с временем N):
 1) Если B==0 --> B:=R-U;
 2) Если S==0 --> S:=U.
 2.1) Иначе (S!=0) и ЕСЛИ U-S > minS тогда:
 2.1.1) d:= Tps * (R-U-B) / (U-S) -- ошибка, тактов таймера за секунду.
 2.1.2) Если |d| > maxD  --> ничего не делать.
 2.1.3) Иначе (|d| < maxD)  -->  D:=((N+1)*D+d)/N, где N -- небольшое целое...
 3) B:=R-U;
 4) S:=U.
Практически синхорнизация выполняется при вызове stime(N), например. time(time_t*) вычисляется как B+U.
Ограничение минимального интервала minS (на уровне десятков-сотен секунд) на котором проводится синхронизация нужно, чтобы не влияли прочие факторы (время передаётся через какой-то канал связи, с задержкой и т.п.) 
Годный вариант?   А как быть нехорошем случае, когда есть два источника времени (внешних), например. И периодически то с одним, то с другим синхронизируется... ?
Вариант, разрешить другой источник только в варианте, когда U-S < N*minS, а тот же источник, если U-S < minS.