Note that there are some explanatory texts on larger screens.

plurals
  1. POConverting between NTP and C# DateTime
    primarykey
    data
    text
    <p>I use the following code to convert between NTP and a C# DateTime. I think the forward corversion is correct, but backwards is wrong.</p> <p>See the following code to convert 8 bytes into a DatTime:</p> <h2>Convert NTP to DateTime</h2> <pre><code>public static ulong GetMilliSeconds(byte[] ntpTime) { ulong intpart = 0, fractpart = 0; for (var i = 0; i &lt;= 3; i++) intpart = 256 * intpart + ntpTime[i]; for (var i = 4; i &lt;= 7; i++) fractpart = 256 * fractpart + ntpTime[i]; var milliseconds = intpart * 1000 + ((fractpart * 1000) / 0x100000000L); Debug.WriteLine("intpart: " + intpart); Debug.WriteLine("fractpart: " + fractpart); Debug.WriteLine("milliseconds: " + milliseconds); return milliseconds; } public static DateTime ConvertToDateTime(byte[] ntpTime) { var span = TimeSpan.FromMilliseconds(GetMilliSeconds(ntpTime)); var time = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc); time += span; return time; } </code></pre> <h2>Convert from DateTime to NTP</h2> <pre><code>public static byte[] ConvertToNtp(ulong milliseconds) { ulong intpart = 0, fractpart = 0; var ntpData = new byte[8]; intpart = milliseconds / 1000; fractpart = ((milliseconds % 1000) * 0x100000000L) / 1000; Debug.WriteLine("intpart: " + intpart); Debug.WriteLine("fractpart: " + fractpart); Debug.WriteLine("milliseconds: " + milliseconds); var temp = intpart; for (var i = 3; i &gt;= 0; i--) { ntpData[i] = (byte)(temp % 256); temp = temp / 256; } temp = fractpart; for (var i = 7; i &gt;= 4; i--) { ntpData[i] = (byte)(temp % 256); temp = temp / 256; } return ntpData; } </code></pre> <p>The following input produces the output:</p> <pre><code>bytes = { 131, 170, 126, 128, 46, 197, 205, 234 } var ms = GetMilliSeconds(bytes ); var ntp = ConvertToNtp(ms) //GetMilliSeconds output milliseconds: 2208988800182 intpart: 2208988800 fractpart: 784715242 //ConvertToNtp output milliseconds: 2208988800182 intpart: 2208988800 fractpart: 781684047 </code></pre> <p>Notice that the conversion from milliseconds to fractional part is wrong. Why?</p> <h2>Update:</h2> <p>As Jonathan S. points out - it's loss of fraction. So instead of converting back and forth, I want to manipulate with the NTP timestamp directly. More specific, add milliseconds to it. I would assume the following function would do just that, but I'm having a hard time validating it. I am very unsure about the fraction-part.</p> <pre><code>public static void AddMilliSeconds(ref byte[] ntpTime, ulong millis) { ulong intpart = 0, fractpart = 0; for (var i = 0; i &lt; 4; i++) intpart = 256 * intpart + ntpTime[i]; for (var i = 4; i &lt;= 7; i++) fractpart = 256 * fractpart + ntpTime[i]; intpart += millis / 1000; fractpart += millis % 1000; var newIntpart = BitConverter.GetBytes(SwapEndianness(intpart)); var newFractpart = BitConverter.GetBytes(SwapEndianness(fractpart)); for (var i = 0; i &lt; 8; i++) { if (i &lt; 4) ntpTime[i] = newIntpart[i]; if (i &gt;= 4) ntpTime[i] = newFractpart[i - 4]; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload