Resort to the good old ICMP Timestamp message scheme. It's fairly trivial to implement in JavaScript and PHP.
Here's an implementation of this scheme using JavaScript and PHP:
// browser.js
var request = new XMLHttpRequest();
request.onreadystatechange = readystatechangehandler;
request.open("POST", "http://www.example.com/sync.php", true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send("original=" + (new Date).getTime());
function readystatechangehandler() {
var returned = (new Date).getTime();
if (request.readyState === 4 && request.status === 200) {
var timestamp = request.responseText.split('|');
var original = + timestamp[0];
var receive = + timestamp[1];
var transmit = + timestamp[2];
var sending = receive - original;
var receiving = returned - transmit;
var roundtrip = sending + receiving;
var oneway = roundtrip / 2;
var difference = sending - oneway; // this is what you want
// so the server time will be client time + difference
}
}
Now for the sync.php
code:
<?php
$receive = round(microtime(true) * 1000);
echo $_POST["original"] . '|';
echo $receive . '|';
echo round(microtime(true) * 1000);
?>
I haven't tested the above code, but it should work.
Note: The following method will accurately calculate the time difference between the client and the server provided that actual time to send and receive messages is the same or approximately the same. Consider the following scenario:
Time Client Server
-------- -------- --------
Original 0 2
Receive 3 5
Transmit 4 6
Returned 7 9
- As you can see, the client and server clocks are 2 units off sync. Hence when the client sends the timestamp request, it records the original time as 0.
- The server receives the request 3 units later, but records the receive time as 5 units because it's 2 units ahead.
- Then it transmits the timestamp reply one unit later and records the transmit time as 6 units.
- The client receives the reply after 3 units (i.e. at 9 units according to the server). However, since it's 2 units behind the server it records the returned time as 7 units.
Using this data, we can calculate:
Sending = Receive - Original = 5 - 0 = 5
Receiving = Returned - Transmit = 7 - 6 = 1
Roundtrip = Sending + Receiving = 5 + 1 = 6
As you can see from above, the sending and receiving times are calculated incorrectly depending upon how much the client and server are off sync. However, the roundtrip time will always be correct because we are first adding two units (receive + original), and then subtracting two units (returned - transmit).
If we assume that the oneway time is always half of the roundtrip time (i.e. the time to transmit is the time to receive, then we can easily calculate the time difference as follows):
Oneway = Roundtrip / 2 = 6 / 2 = 3
Difference = Sending - Oneway = 5 - 3 = 2
As you can see, we accurately calculated the time difference as 2 units. The equation for time difference is always sending - oneway
time. However, the accuracy of this equation depends upon how accurately you calculate the oneway time. If the actual time to send and receive the messages is not equal or approximately equal, you'll need to find some other way to calculate the one way time. However, for your purposes this should suffice.