Calculating the time difference in an PHP/MySQL/JavaScript system - php

I was wondering what the best way is to calculate the difference in time from now to a certain point, let's say the countdown time.
I have an auction that has a closetime at a certain point, this time is stored in a MySQL record in the format " DATETIME 00-00-000 00:00:00 ". This record is called closetime.
Now on my website I have JavaScript code that gets this time via a PHP file. The JavaScript loops every second using setInterval 1000. The PHP file gets the closetime from the db, and sends it back in this format
strtotime($result['closetime']);
And I get the time of the request, I want to use the server time, and not the time in JavaScript, because the clock of the user can be off.
strtotime(date("H:i:s", $_SERVER['REQUEST_TIME']))
I send back these two timestamps and calculate the time difference between them in JavaScript. I use this function to do it, the values send back from PHP I call currentTime and closeTime, I think this should be clear.
function auctionDelayTime(currentTime,closeTime){
totaldelay = closeTime - currentTime;
if(totaldelay <= 0){
return 'ended';
}else{
if( days=parseInt((Math.floor(totaldelay/86400))) )
totaldelay = totaldelay % 86400;
if( hours=parseInt((Math.floor(totaldelay/3600))) )
totaldelay = totaldelay % 3600;
if( minutes=parseInt((Math.floor(totaldelay/60))) )
totaldelay = totaldelay % 60;
if( seconds=parseInt((Math.floor(totaldelay/1))) )
totaldelay = totaldelay % 1;
return hours+':'+formatTimes(minutes)+':'+formatTimes(seconds);
}
}
function formatTimes(value){
return value < 10 ? '0'+value : value;
}
I think this is an awful lot of code do something so simple. Does anyone have a better solution or maybe more 'beautiful' code.
Enjoy!

There is a jquery Countdown Plugin that supports server sync through AJAX:
From the docs:
Synchronise the client's time with
that of the server by providing a
function that returns the current
server date and time. This date and
time should take into account the
server's timezone and any difference
between that time and the client's is
applied to the countdown when it is
started or changed.
The following example uses a PHP
program on the server to return the
current server time in a format that
can be used directly by the JavaScript
callback. You should make sure that
your server call is synchronous.
$(selector).countdown({
until:liftoffTime, serverSync: serverTime});
function serverTime() {
var time = null;
$.ajax({url: 'http://myserver.com/serverTime.php',
async: false, dataType: 'text',
success: function(text) {
time = new Date(text);
}, error: function(http, message, exc) {
time = new Date();
}});
return time;
}
serverTime.php:
<?php
$now = new DateTime();
echo $now->format("M j, Y H:i:s O")."\n";
?>

Use Date object.
var d = new Date(difference_in_milliseconds);
var seconds = d.getSeconds();
var minutes = d.getMinutes();
var hours = d.getHours() - 1; //See note
Note: Strangely, hours value is bigger by one than I would expect for reason I don't understand. It looks like "midnight Jan 1, 1970" was at 1 AM :-)
UPDATE: The difference of 1 is due to the offset of my timezone (GMT +1).
Slight change that will solve this:
var d = new Date();
var offset = d.getTimezoneOffset() * 60000;
var d = new Date(difference_in_milliseconds + offset);
var seconds = d.getSeconds();
var minutes = d.getMinutes();
var hours = d.getHours();

This JavaScript library is easy to use and will likely serve you well.

Why not have the php page give you the difference?
$sql = "SELECT UNIX_TIMESTAMP(NOW()) as currentTime, UNIX_TIMESTAMP(closeTime) as closeTime FROM yourTable WHERE yourRecordId = '123'";
$query = mysql_query($sql);
$result = mysql_fetch_assoc($query);
echo timeRemaining($result['currentTime'], $result['closeTime']);
function timeRemaining($start, $end) {
$dateDiff = $end - $start;
if ($dateDiff <= 0) { return 'Ended'; }
$fullDays = floor($dateDiff/(60*60*24));
$fullHours = floor(($dateDiff-($fullDays*60*60*24))/(60*60));
$fullMinutes = floor(($dateDiff-($fullDays*60*60*24)-($fullHours*60*60))/60);
return "Ending in $fullDays days, $fullHours hours and $fullMinutes minutes.";
}

Do you really have to get the time through AJAX every 1000 ms?
(i suppose that you're hoping for closetime changes? ...)
But if you really must do it this way, i'd suggest getting the time difference directly in MySQL for code simplicity.
$sql = "SELECT TIMEDIFF(NOW(), `CreateTime`) from `Table` WHERE `id`=1;"

Related

compare user time zone (anywhere in the world) to current Pacific+one hour in PHP

This project includes creating a form for users to enter the start and end time of a promotion. The site where the promotion will be live operates in the Pacific Time Zone and the user creating the promotion could be anywhere in the world.
The start time must be one hour greater than the current PST (or PDT depending on season). The current method of validating the start time is not working because it pulls the local time of the user's computer.
I need a way to compare the user's local time to Pacific Time and validate that the promotional start time is one hour greater.
My working theory is to find the offset between the user's local time and GMT time, then find the offset between current Pacific time and GMT (which varies by 7 or 8 hours depending on DST--right?), then apply these offsets to the user's time and compare to Pacific time plus one hour.
I have succeeded in finding the necessary offsets and alerting the correct current time in Pacific time in various strings and timestamps but the overall logic escapes me. Also, I have been unable to successfully add one hour to a TimeStamp.
this question is similar, and many others, but in this case the OP has a fixed offset:
Compare user's time zone with the website's office location time zone
Current code:
function valid() {
var starttime=$('#1-PromotionalSaleStartTime').val();
var endtime=$('#1-PromotionalSaleEndTime').val();
var now = new Date();
var hour= now.getHours();
var min = now.getMinutes()+10;
var nows= parseInt(hour)+1;
var time=nows+':'+min;
var presentime = now.getHours()+':'+now.getMinutes()
var month =now.getMonth()+1;
var day = now.getDate();
var output = (month<10 ? '0' : '') + month + '/' +(day<10 ? '0' : '') + day + '/' + now.getFullYear() + ' '+time;
var now = (month<10 ? '0' : '') + month + '/' +(day<10 ? '0' : '') + day + '/' + now.getFullYear() + ' '+presentime;
var present = new Date(now);
var oneDay = 24*60*60*1000; // hours*min*sec*milliseconds
var firstDate = new Date(starttime);
var secondDate = new Date(endtime);
var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime())/(oneDay)));
var diff = Math.round(Math.abs(( present.getTime() - firstDate.getTime())/(oneDay)));
var presentTimeStamp = +'<?php echo time(); ?>' * 1000;
var firstDateTimeStamp = Date.parse($('#1-PromotionalSaleStartTime').val());
var err = 0;
<?php if($this->add!="" && isset($this->add)) {?>
if(presentTimeStamp > firstDateTimeStamp) {
$('#1-PromotionalSaleStartTime').after('<ul class="errors"><li>Sorry, but you cannot add past date.</li></ul>');
err++;
}
<?php } ?>
if(diffDays==0){
$('#1-PromotionalSaleEndTime').after('<ul class="errors"><li>The date difference between Start and End dates should be 24 hours.</li></ul>');
err++;
}
if(starttime < output){
$('#1-PromotionalSaleStartTime').after('<ul class="errors"><li>Your Start time should be at least 1 hour more than the current Pacific Time like. '+ output +'</li></ul>');
err++;
}
if((Date.parse(starttime)> Date.parse(endtime)) ){
$('#1-PromotionalSaleEndTime').after('<ul class="errors"><li>End Time cannot be less than Start Time plus 1 day.</li></ul>');
err++;
}
Try this on the Server side:
/* timetest.php */
<?php
if(isset($_POST['dateInfo'])){
date_default_timezone_set('America/Los_Angeles'); $data = array();
$dt = new DateTime;
$pacificPlusOneOffset = dt->add(new DateInterval('P1D'))->getOffset();
$data['diff'] = +$_POST['dateInfo']-$pacificPlusOneOffset;
echo json_encode($data);
}
else{
// could be some kind of hack
}
?>
AJAX should send JavaScript on the Client side, like:
var pre = onload;
onload = function(){
if(pre)pre();
// more code to run other code here
function post(url, send, success){
var x = new XMLHttpRequest || new ActiveXObject('Microsoft.XMLHTTP'), ec = [], s;
for(var i in send){
ec.push(encodeURIComponent(i)+'='+encodeURIComponent(send[i]));
}
s = ec.join('&').replace(/%20/g, '+'); x.open('POST', url);
x.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
x.setRequestHeader('Content-length', s.length);
x.setRequestHeader('Connection', 'close');
x.onreadystatechange = function(){
if(x.readyState === 4 && x.status === 200 && success){
success(eval('('+x.responseText+')'));
}
}
x.send(s);
}
post('timetest.php', {dateInfo:new Date().getTimezoneOffset()}, function(result){
console.log(result.diff);
})
}

How to get first time from server by php and put in JavaScript

How can I get first time from server by php?
I've tested this code but it does not work. It gets the time but it is not counting? What's the problem?
<script type="text/javascript">
function GetClock(){
d = new Date(<?php echo date("y, n, j, G, i, s");?>);
nhour = d.getHours();
nmin = d.getMinutes();
nsec = d.getSeconds();
if(nhour == 0) {
ap = " AM";nhour = 12;
} else if(nhour <= 11) {
ap = " AM";
} else if(nhour == 12) {
ap = " PM";
} else if(nhour >= 13) {
ap = " PM";nhour -= 12;
}
if(nmin <= 9) {
nmin = "0" +nmin;
} if(nsec <= 9) {
nsec = "0" +nsec;
}
document.getElementById('clockbox').innerHTML=""+nhour+":"+nmin+":"+nsec+ap+"";
setTimeout("GetClock()", 1000);
}
window.onload=GetClock;
</script>
Explanation
The question is why are you using PHP to write a datetime into the Date object in JS?
The PHP will only write out the time at the point at which the page renders, it will never change again.
You are then setting your counter based on a Javascript setTimeout every 1 second, expecting the clock to increment in seconds, but it is always based on the same original time (the page render time) and is always incremented by 1 second.
For example. The page loads at 12:00:00 on June 3 2013. Your code looks like this:
d = new Date(13, 6, 3, 12, 0, 0);
at the time the pages loads (if you view source)
1 second later the setTimeout fires and renders the clock at 12:0:01, based on the starting time in the date object.
But your starting time never changes, so each further second that passes and triggers setTimeout will base the calculations on 12:00:00 not the current time
TLDR; and answer
Remove the PHP!
d = new Date();
Alternatively, if you absolutely have to use server time. You would need to initialise the date object as you have done, but then store a count of how many seconds have passed and calculate the difference

GMT Time format to integer format

I am trying to show ticker clock for different timezone. When I looked around the web, it looks like it takes number for the offset(for example +5.5 hours) in javascript. But the way we are getting the gmtformat is +05:30 in php which I am trying to feed in to the javascript function. Is there any function that I can use to convert?
/*CLOCK CODE IN JAVASCRIPT*/
function startclock(field, timediff, newOrRepeat)
{
var clockAction=newOrRepeat;
if (timediff=="") {$(field).html("-------");return false;}
/****THERE ARE MORE STUFF IN BETWEEN AND AFTER WHICH IS NOT RELEVANT TO OFFSET****/
var secondsDiff=0;
var secondsTimeZone = 0;
//calculate the difference in time set by both the timezone as well as the DST
secondsTimeZone = parseInt(timediff);
if ($("input[name='daylight']:checked").val()=="on" && $(field).siblings("#isDaylight").val()=="no")
secondsDiff=secondsTimeZone + 3600;
else if ($("input[name='daylight']:checked").val()=="off" && $(field).siblings("#isDaylight").val()=="yes")
secondsDiff=secondsTimeZone - 3600;
else
secondsDiff = secondsTimeZone;
var thetime=new Date();
thetime.setUTCSeconds(parseInt(thetime.getUTCSeconds())+parseInt(secondsDiff));
var nhours=thetime.getUTCHours();
var nmins=thetime.getUTCMinutes();
var nsecn=thetime.getUTCSeconds();
}
I am getting getting gmt format straight from php which i am passing to this function.
function convert_time($time){
$parts = explode(':', $time);
return $parts[0] + number_format($parts[1]/60, 2);
}

Client time settings broke readable date in javascript

What i'm trying to do is show date in more readable format like 3 seconds ago, 1 hours ago, yesterday, June 12 and etc.
What i did is , first calculate the timestamp for comment's date.. Then send it to client with ajax, then create two date instance on javascript one for is comment's date and other one is current date.. After that I just find differences between to date item then write on the screen with fancy words..
Everything works fine on localhost, even server.. But sometimes if client's pc date is earlier from the server date (independent from time zone)..
Let say server time is today 13.30 pm and client time is today 13.00 , it's failing with this scenario because current time is being comment's post time.. Difference will be negative value..
I'm creating date object for comment in php like this;
date("Y-m-d G:i:s")
Then write it to mysql db..
After that when i select comments i convert it to timestamp to push it on client side with ;
$comment['timestamp'] = strtotime($row['creationDate']);
And then in javascript, I make calculation for human readable date format ;
DateObject.getFormatted = function(unixtime){
d = new Date(unixtime*1000);
now = new Date();
var diff = (now.getTime()/1000- unixtime) ;
var result = "";
var MIN = 60,
HOUR = 3600,
DAY = 86400;
if(diff < 2)
result ="just now";
else if(diff < MIN)
result = Math.floor(diff) + " seconds ago";
else if(diff < HOUR)
result = Math.floor(diff/60) + " minutes ago";
else if(diff < DAY)
result = Math.floor(diff/3600) + " hours ago";
else if(diff < DAY*3)
{
var days = diff/DAY;
if(days < 2)
result = "yesterday";
else
result = Math.floor(days) + " days ago";
}
else if(now.getFullYear() == d.getFullYear())
{
formattedTime = this.getTime(d);
result = this.getSameYear(d) + " at " + formattedTime;
}
else
{
formattedDate = this.getDate(d);
formattedTime = this.getTime(d);
result = formattedDate + " at " + formattedTime;
}
return result;
};
So if clients date is earlier then the comment's date diff value is being negative, so the first case would be true
if(diff < 2)
result ="just now";
It's going behing as time difference between client and comment's date .. In my case 10 minutes.. If I set my computer time 10 minutes later it's working nice..
So how can i fix it in a better way?
Thank you.
May be better send from server to client difference between comment date and current date?(instead of creation two javascript date instances)
A third date so you can calculate the difference between server and client and use it as an offset?

How can I get the user's local time instead of the server's time?

How can I get the time of the client side?
When I use date() it returns server's time.
Here's a "PHP" solution:
echo '<script type="text/javascript">
var x = new Date()
document.write(x)
</script>';
As mentioned by everyone PHP only displays server side time.
For client side, you would need Javascript, something like the following should do the trick.
var currentTime = new Date();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
if (minutes < 10) {
minutes = "0" + minutes;
}
document.write("<b>" + hours + ":" + minutes + " " + "</b>");
And if you want the AM/PM suffix, something like the following should work:
var currentTime = new Date();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
var suffix = "AM";
if (hours >= 12) {
suffix = "PM";
hours = hours - 12;
}
if (hours == 0) {
hours = 12;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
document.write("<b>" + hours + ":" + minutes + " " + suffix + "</b>");
Here is a list of additional JavaScript Date and Time functions you could mess around with.
You could possibly use Geolocation by IP Address to work out which country the user is in, and then use that.
But using Javascript or letting the user choose a Timezone will probably be better.
As PHP runs on the server-side, you cannot access the client-side time from PHP : PHP doesn't know much about the browser -- and you can have PHP scripts that run without being called from a browser.
But you could get it from Javascript (which is executed on the client-side), and, then, pass it to PHP via an Ajax request, for example.
And here are a couple of questions+answers that might help you getting started :
Automatically detect user’s current local time with JavaScript or PHP
How can I determine a web user’s time zone?
PHP is server side only as far as i know.
You maybe want to use JavaScript.
As other's have mentioned, you can use Geo Location Services based on the IP Address.
I found it to be off by about 18 seconds due to IP location accuracy, by using a $responseTime offset it helped me narrow it down to 2 second accuracy in the Viewers Location.
<?php;
echo deviceTime('D, M d Y h:i:s a');
function deviceTime($dateFormatString)
{
$responseTime = 21;
$ip = (isset($_SERVER["HTTP_CF_CONNECTING_IP"])?$_SERVER["HTTP_CF_CONNECTING_IP"]:$_SERVER['REMOTE_ADDR']);
$ch = file_get_contents('https://ipapi.co/'.$viewersIP.'/json/');
$ipParts = json_decode($ch,true);
$timezone = $ipParts['timezone'];
$date = new DateTime(date('m/d/Y h:i:s a', time()+$responseTime));
$date->setTimezone(new DateTimeZone($timezone));
return $date->format($dateFormatString);
}
?>

Categories