tags:

views:

145

answers:

2

I'm developing an application and I need to get the current date from a server (it differs from the machine's date). I receive the date from the server and with a simple Split I create a new DateTime:

globalVars.fec = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, int.Parse(infoHour[0]), int.Parse(infoHour[1]), int.Parse(infoHour[2]));

globalVars is a class and fec is a public static variable so that I can access it anywhere in the application (bad coding I know...). Now I need to have a timer checking if that date is equal to some dates I have stored in a List and if it is equal I just call a function.

List<DateTime> fechas = new List<DateTime>();

Before having to obtain the date from a server I was using computer's date, so to check if the dates matched I was using this:

private void timerDatesMatch_Tick(object sender, EventArgs e)
{
    DateTime tick = DateTime.Now;
    foreach (DateTime dt in fechas)
    {
        if (dt == tick)
        {
            //blahblah
        }
    }
}

Now I have the date from the server so DateTime.Now can't be used here. Instead I have created a new timer with Interval=1000 and on tick I'm adding 1 second to globalVars.fec using:

globalVars.fec = globalVars.fec.AddSeconds(1);

But the clock isn't accurate and every 30 mins the clock loses about 30 seconds.

Is there another way of doing what I'm trying to do? I've thought about using threading.timer instead but I need to have access to other threads and non-static functions.

+6  A: 

Store the difference between the server's time and local time. Calculate the servers' time when you need it using that difference.

Billy ONeal
Didn't think about that, I was just thinking on hard solutions when the real solution was pretty easy. Thanks!
Ivan
Yes, but that needs to be re-calibrated every so often.
Henk Holterman
Why? I just store the difference between server's time and local time in a TimeSpan and when I need to check if dates match i just do DateTime.Now.Add(timespan_diff);
Ivan
And how reliable are bot the server and client clocks? What is the risk of someone/something changing the clock? Have you consider what happens when daylight-savings changes?
Henk Holterman
+3  A: 

If you create atimer with an interval of 1000ms, it will be called no sooner than 1000ms. So you can pretty much guarantee that it will be called in more than 1000ms, which means you will "lose" time by adding 1s on this timer tick - This will accumulate error with every tick. A better approach is to record a start time and use the current time to determine the current offset from that known start time, so that you don't accumulate any error in your time keeping. (There will still be some error, but you will not drift out of touch with real-time over time)

Different timers (Forms.Timer, Thread.Timer etc) will give different accuracies as well - Forms.Timer is particularly poor for accuracy.

You could also use a high performance time to keep track of the time better - see here, for example.

Jason Williams