我有这段代码:
<p id="demo"></p>
<script>
// Set the date we're counting down to
var countDownDate = new Date("<?php echo $starttime; ?>").getTime();
// Update the count down every 1 second
var x = setInterval(function() {
// Get todays date and time
var now = new Date("<?php echo $nowtime; ?>").getTime();
// Find the distance between now an the count down date
var distance = - countDownDate + now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hoursdiff = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
// Display the result in the element with id="demo"
document.getElementById("demo").innerHTML = days + "d " + hours + "h "
+ minutes + "m " + seconds + "s ";
// If the count down is finished, write some text
if (distance < 0) {
clearInterval(x);
document.getElementById("demo").innerHTML = "EXPIRED";
}
}, 1000);
</script>
它执行并计算从DB中提取的2个日期之间的时差。它应该每秒更新差异作为秒表,但由于某种原因,它显示差异一次,间隔功能停止工作。
但如果我从&#39;现在&#39;删除"<?php echo $nowtime; ?>"
变量,它开始像魅力一样工作。
答案 0 :(得分:0)
为什么不简单地使用javascript方法Date().getTime()
,而不是尝试在实际函数中使用php来获取当前时间(现在)?页面加载后,php变量不会更新,因此日期函数将始终引用相同的时间
<p id="demo"></p>
<script>
<?php
/* example date */
$starttime='2017-08-20 14:30:30';
echo "
var countDownDate = new Date('$starttime').getTime();
";
?>
(function(time){
var now=new Date().getTime();
// Find the distance between now an the count down date
var distance = countDownDate - now;
// Time calculations for days, hours, minutes and seconds
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hoursdiff = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
t=setTimeout( arguments.callee, time );
if( distance <= 0 ){
clearTimeout( t );
return false;
}
document.getElementById("demo").innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
})(1000);
</script>
为了在不使用ajax长轮询的情况下实现服务器时间的持续轮询,我认为Server Sent Events是理想的。下面的第一个脚本是SSE中使用的服务器组件 - 它每隔X秒将格式化的消息发送回javascript客户端,在这种情况下每1秒发送一次。
<?php
/* sse-time.php */
set_time_limit( 0 );
ini_set('auto_detect_line_endings', 1);
ini_set('max_execution_time', '0');
ob_end_clean();
$sleep = 1; /* send message back every X seconds */
$startdate = !empty( $_GET['start'] ) ? $_GET['start'] : false;
$evt = !empty( $_GET['evt'] ) ? $_GET['evt'] : 'time';
if( $startdate ){
/*
utility function to send formatted response
*/
function sse( $evtname='sse', $data=null, $retry=1000 ){
if( !is_null( $data ) ){
echo "event:".$evtname."\r\n";
echo "retry:".$retry."\r\n";
echo "data:" . json_encode( $data, JSON_FORCE_OBJECT | JSON_HEX_QUOT | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS );
echo "\r\n\r\n";
}
}
/*
Important to set correct headers
*/
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Expose-Headers: X-Events');
/* Infinite loop */
while( true ){
if( connection_status() != CONNECTION_NORMAL or connection_aborted() ) {
break;
}
/* If the current date/time is greater than countdown target, exit loop */
if( time() > $startdate ) break;
/* construct the payload */
$payload=array(
'event' => $evt,
'date' => date( 'Y-m-d H:i:s' ),
'start' => $startdate
);
/* send the payload */
call_user_func( 'sse', $evt, $payload );
/* -- Send output -- */
if( @ob_get_level() > 0 ) for( $i=0; $i < @ob_get_level(); $i++ ) @ob_flush();
@flush();
/* wait for defined period before repeating loop */
sleep( $sleep );
} //end infinite loop
if( @ob_get_level() > 0 ) {
for( $i=0; $i < @ob_get_level(); $i++ ) @ob_flush();
@ob_end_clean();
}
}
?>
客户端组件包含在一个基本的html页面中,以显示wholoe的工作原理。
<?php
/* countdown */
$starttime='2017-08-21 10:58:30';
?>
<!doctype html>
<html>
<head>
<title>SSE Countdown</title>
<script>
<?php
echo " var countDownDate = new Date('$starttime').getTime();";
?>
function bindEvtSource(){
var evtname='time';
var url='https://sentinel/assets/sse-time.php?start='+countDownDate+'&evt='+evtname;
var demo=document.getElementById('demo');
if ( !!window.EventSource ) {
var evtSource = new EventSource( url );
evtSource.addEventListener( 'error', function(e){
console.error('%o %s',e,e.type);
},false);
evtSource.addEventListener( evtname, function(e){
var json=JSON.parse(e.data);
var now=new Date( json.date ).getTime();
var distance = countDownDate - now;
var days = Math.floor(distance / (1000 * 60 * 60 * 24));
var hoursdiff = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
demo.innerHTML = days + "d " + hours + "h " + minutes + "m " + seconds + "s ";
if( distance <= 0 ){
evtSource.close();
demo.innerHTML='EXPIRED';
}
},false);
} else {
demo.innerHTML='Server Sent Events are not supported in this browser';
}
}
document.addEventListener( 'DOMContentLoaded', bindEvtSource, false );
</script>
</head>
<body>
<p id='demo'></p>
</body>
</html>
答案 1 :(得分:0)
很抱歉迟到的回复。
我决定用javascript来更新我从db中获取的时差。具体来说,我正在刷新页面的一部分而不是整个页面。它现在就像一个秒表。
1)启动计数器
<a href="http://127.0.0.1:4567/home_controller/startcount">start count</a><br>
<?php if (!empty($timer->start)){$date1=date_create($timer->start);
$date2=date_create(date('Y-m-d H:i:s'));
$diff=date_diff($date1,$date2);
$days = $diff->format("%d");
$hours = $diff->format("%h");
$minutes = $diff->format("%i")/60;
$seconds = $diff->format("%s")/360;
$timediff = $hours+$minutes+$seconds;}
?>
2)刷新显示时差的部分。
<div id="scope"><?php if (!empty($timer->start)){echo $diff->format("%d days %h hours %i minutes %s seconds");} ?></div> <script type="text/javascript">
var $scores = $("#scores");
setInterval(function () {$("#scope").load("http://127.0.0.1:4567/home_controller/ #scope");
}, 1000);
</script>