5

Given a timestamp string coming from another machine A to machine B (for example, hh:mm:ss.fff) and assuming both machines' clocks to be synchronised, how can I make machine B calculate the timespan between its clock and the time in the string coming from machine A?

I've tried comparing with DateTime.Now.Ticks, but the resolution seems to be 10-20 ms. I would like to calculate closer to a 1 ms resolution.

For some time now, I've had success in using Stopwatch.GetTimestamp() for high-resolution timing, but keep in mind it's not that simple since I only have the string available in machine B, and no great way to calibrate Stopwatch.GetTimestamp with an actual system time.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
Alan
  • 2,574
  • 2
  • 18
  • 16
  • 2
    What kind of resolution do you require? – Oded Jan 07 '13 at 18:03
  • And what resolution of your time synchronization (as system one will not provide anything better that system clock resolution that is about 15ms). – Alexei Levenkov Jan 07 '13 at 18:04
  • You can get better resolution by pinvoking timeBeginPeriod(1). It doesn't make sense to actually do this, the thread scheduling granularity is much worse. You'll easily lose the processor for 45 msec or more. – Hans Passant Jan 07 '13 at 18:20
  • Duplicate [C# + high resolution timer](http://stackoverflow.com/questions/7137121/c-sharp-high-resolution-timer) or [How to get timestamp of tick precision in .NET / C#?](http://stackoverflow.com/questions/1416139/how-to-get-timestamp-of-tick-precision-in-net-c) – Algirdas Jan 07 '13 at 18:41
  • 2
    not a duplicate -- this involves 2 machines. read carefully. – Alan Jan 07 '13 at 19:40
  • Sorry -- actually IS a duplicate from http://stackoverflow.com/questions/1416139/how-to-get-timestamp-of-tick-precision-in-net-c/1416188#1416188 – Alan Jan 09 '13 at 19:39

2 Answers2

3

DateTime.Now uses the underlying OS's date, which has resolution of about 15 ms, or even worse with pre-Windows XP systems. The best you can get is the High-Resolution-Timer available exactly in the Stopwatch and its ticks/clocks.

You will have to first synchronize the clocks, but that DOES NOT MEAN "set the system's date". Synchronizing clocks means to calculate the difference between the readings, optionally validating if it is constant as the time flows (that is, checking whether none of the clocks counts faster than others) and then using the calculated offset to .. offset the readings so that the "actual values" are relative on the same time-base -- which is of your choice.

Google for "clock synchronization algorithms" to read a lot more about it.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
quetzalcoatl
  • 32,194
  • 8
  • 68
  • 107
  • 1
    Straight from [rotor](http://www.microsoft.com/en-us/download/details.aspx?id=4917) `clr/src/bcl/system/datetime.cs:842`: "[DateTime.Now] Returns a DateTime representing the current date and time. The resolution of the returned value depends on the system timer. For Windows NT 3.5 and later the timer resolution is approximately 10ms, for Windows NT 3.1 it is approximately 16ms, and for Windows 95 and 98 it is approximately 55ms." – allonhadaya Dec 02 '13 at 21:37
  • This was exactly what I meant. I knew that on pre-XP that was ~50ms, but I was not sure enough to write it. Thank you for a good reference! – quetzalcoatl Dec 03 '13 at 09:44
2

Can't you do something like:

  • Call Stopwatch.GetTimestamp() on machine A
  • Send result to Machine B
  • Call Stopwatch.GetTimestamp() on machine B
  • Send result to Machine A
  • Call Stopwatch.GetTimestamp() on machine A
  • Calculate the adjustment factor (difference between average result for machine A and the result for machine B)
  • Use this adjustment factor when comparing subsequent results on machine A and B
Joe
  • 122,218
  • 32
  • 205
  • 338