Kylie
Kylie

Reputation: 11749

PHP Time to Javascript Clock

I want to simply just pull the time from the server. And continue it ticking with javascript.

My PHP.

//Get current UNIX timestamp (no offset, just straight timestamp)
$time = time()*1000;

//Get offset of server time
$offset = date('O');

// Convert into a new timestamp based on the timezone
$newtime = $time+$offset;

// a vardump($newtime) here gives me
// 1415169764400 

My Javascript...

$(document).ready(function(){

// Here Im putting the server time into a variable
var serverTime = "<?php echo $newtime;?>"; 
//console.log(serverTime) gives me 1415169764400

// Local computer time into a variable
var localTime = new Date().getTime(); 
//console.log(localTime) here gives me 1415170692954

// Offset between the computer and the server
var timeDiff = serverTime - localTime; 
// console.log(timeDiff) here gives me -928554  

//The ticking clock function
setInterval(function () {
    // Set clock to Computer time plus the time difference
    var today = new Date(Date.now()+timeDiff);
    var h=today.getHours();
    var m=today.getMinutes();
    var s=today.getSeconds();
    m = checkTime(m); //checktime() is just a leading zero function
    s = checkTime(s); // checktime() is just a leading zero function
    var formatted = h+":"+m+":"+s;
    $('.serverTime').html(formatted);
}, 2000);
//PROBLEM IS THAT THIS DISPLAYS THE CURRENT TIME ON MY COMPUTER
// NO MATTER WHAT I TRY, IT ALWAYS JUST DISPLAYS THE LOCAL TIME
// No matter what PHP timezone I put.
// The time Diff and server times are working properly.
// Any ideas whats happening!!???
});

I normally would just use the users local computer time, but each server is in a different location, and when they are visiting this page, I want the clock to tick to the server they're currently visiting.

Upvotes: 2

Views: 2962

Answers (2)

gilly3
gilly3

Reputation: 91497

$time is the number of seconds since unix epoch, expressed as milliseconds. $offset is the number of hours difference from GMT*, Eg '-0800'. Your first problem is that you are adding the offset to the timestamp. At most, you are changing the time by 1.4 seconds, where you seem to intend to change the time by hours.

It would be much easier if you use a DateTime object instead. Then you can call .getOffset() which gives you the difference in seconds:

<?php 
$date = new DateTime();

// Get offset for UNIX timestamp based on server timezone
$time = $date->getTimestamp();

//Get offset of server time
$offset = $date->getOffset();

// Convert into a new timestamp based on the timezone
$newtime = ($time + $offset) * 1000;
?>

So far, we've been dealing only with UTC dates. Your other problem is that you are using the local date methods to get values out. You should use the UTC versions of these methods.

//Actual ticking clock
setInterval(function () {
    var today = new Date(Date.now() + timeDiff);
    var h=today.getUTCHours();
    var m=today.getUTCMinutes();
    var s=today.getUTCSeconds();
    m = checkTime(m);
    s = checkTime(s);
    var formatted = h+":"+m+":"+s;
    $('.serverTime').html(formatted);
}, 2000);

Here's the whole thing, with simulated server time:

function simulateServerTime() {
    var time = new Date();
    // Add 1 minute and 12 seconds to simulate the clocks being a little out of sync
    time.setMinutes(time.getMinutes() + 1, 12);
    // Reduce to seconds to simulate php
    time = Math.round(time / 1000);
    // Specify an offset of -6 hours
    var offset = -6 * 60 * 60;
    return (time + offset) * 1000;
}

var serverTime = simulateServerTime();

var localTime = new Date();

// Offset between the computer and the server
var timeDiff = serverTime - localTime;

// The ticking clock function
setInterval(function () {
  var today = new Date(Date.now() + timeDiff);
  var h=today.getUTCHours();
  var m=today.getUTCMinutes();
  var s=today.getUTCSeconds();
  m = checkTime(m);
  s = checkTime(s);
  var formatted = h+":"+m+":"+s;
  document.querySelector(".serverTime").innerHTML = formatted;
}, 1000);

// Helper function for leading 0's
function checkTime(i) {
  if (i<10) {i = "0" + i};  // add zero in front of numbers < 10
  return i;
}
<div class="serverTime"></div>


*Or, so says the documentation. Last week, my machine said -0700, which is the octal representation of -448. My time is neither 700 hours earlier than GMT, nor is it 448 hours earlier than GMT, it's 7 hours earlier. It annoys me that the documentation states that it is the time offset in hours, when really it's the time offset in ISO 8601 Format.

Upvotes: 2

gwokae
gwokae

Reputation: 76

Timestamp is not include timezone offset. Everyone's unix time is a offset from Jan 1, 1970 in UTC

If you wish to display a server timezone in client, your PHP must provide a server timezone. And about client timezone, you can reference this .

Also, I like to using moment.js to handle date/time problems.


I just modified the client side javascript, using moment. Wish it's all you needed

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
<?php

date_default_timezone_set("Europe/Athens");

$serverTime =  time() * 1000 ;
$timezone = date('O');

?>
<div id="result"></div>
<script>
  var serverTime = <?php echo $serverTime;?>,
    timezone = "<?php echo $timezone;?>",
    timeDiff = serverTime - Date.now();

  setInterval(function () {
      result.innerHTML= moment().add(timeDiff).zone(timezone).format('HH:mm:ss Z') + "<br/>" + result.innerHTML  ;
  }, 2000);
</script>

Upvotes: 0

Related Questions