I see you´re updating the label every timer ticks and although it´s not shown in the code it looks like your timer interval its set to 1 second probably, Am I right?.
The first thing you´re doing bad is trusting the 1 second interval you set up previously in your timer and hard-coding your code to that interval. The fact is you can´t rely in the timer interval to be precise because most of the timers have a awful resolution time of approximately 14 - 16 ms therefore that´s not a precise way to measure time.
You should use instead the time System.Diagnostics.Stopwatch class which uses the Win32 APIs QueryPerformanceFrequency and QueryPerformanceCounter. Those are the more reliable ways and fast ways to measure time due to the fact that Windows isn´t a Real Time Operation System.
As for how the code will look using I let a sample which should be pretty easy to adapt for you. Besides I include a solution for your TimeSpan - String translation trouble.
class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
Console.WriteLine("Starting..");
sw.Start();
Console.ReadLine();
sw.Stop();
Console.WriteLine("Elapsed time {0}:{1}:{2}:{3}", sw.Elapsed.Hours.ToString("00"), sw.Elapsed.Minutes.ToString("00"), sw.Elapsed.Seconds.ToString("00"), sw.Elapsed.Milliseconds);
}
}
Be careful while using the System.Diagnostics.Stopwatch properties, there is a big difference in using the Elapsed.Ticks property and the ElapsedTicks property which it´s explained here.
Hope it helps!!