SniperCode Sheva
asked on
How to use embargo Date/time in php
Hello, I have a website, and in my website, I want to create a game each Monday for example, so before launching the game I want to put a countdown so that when it arrived at a certain time the game appears...
ASKER
There is a problem here, it is the countdown. The countdown is not realtime when I launch the page. But the idea is here.
ASKER
Is it possible to only put the time not the date.
Comparing only the time for example I want the game to be shown when 10:10 comes but before the countdown is in realtime, I don't care what the date is.
thank you.
Comparing only the time for example I want the game to be shown when 10:10 comes but before the countdown is in realtime, I don't care what the date is.
thank you.
The countdown is not realtime when I launch the pageTo the contrary (and this is why I posted the links to the articles -- the articles exist because these are common topics, and it's too much information to repeat for every individual question). When you launch the page, your browser makes an HTTP request to the server, and the response is generated in as close to "real time" as is technologically feasible in modern networks. Each time your browser makes an HTTP request to the server, the server will respond with its "real time" response, unless you've done something to incorporate caching, which would not really make sense for an application like this one. You can click the "refresh" button on your browser and the page will be refreshed. As you do that you will see that the response changes every time, as time marches forward toward the embargo date/time.
You can also use an AJAX request to the browser to reload the information from the server. But you don't really need to do that more than once, because the timing information in the server and in the client browser are going to be highly consistent. If you find that there is some divergence between the server and client times, you're either dealing with a huge load on the client (runaway JavaScript in another window) or a hardware malfunction. IIRC in Julian's example, he showed how to repeat the HTTP request to the server so that you can get a new set of timing information to restart your JavaScript application that animates the countdown timer in the browser viewport. You might try it both ways, and see if there is any value to recalling the server. In any case, there will be very little "cost" to recalling the server.
To the issue of only time and not date, the answer is "yes, of course." Your internal application on the server will use a DateTime object, but when you format the information for browser display, you will choose the formatting that shows exactly what you want to show to the client. Please see Producing "Pretty" Dates From DateTime Objects, Computing the Difference Between DateTime Objects, and Time Without Date in this article:
https://www.experts-exchange.com/articles/20920/Handling-Time-and-Date-in-PHP-and-MySQL-OOP-Version.html
Just for interest here is a variation on the code posted in the previous question that shows two timers both seeded from the server.
The first refreshes from the server every 15 seconds
The second simply decreases last time by 1000ms
You can run it to see if they two times deviate sufficiently to warrant a callback.
The first refreshes from the server every 15 seconds
The second simply decreases last time by 1000ms
You can run it to see if they two times deviate sufficiently to warrant a callback.
<div><span id="days"></span> days <span id="hours"></span> hours <span id="minutes"></span> minutes <span id="seconds"></span> seconds </div>
<div><span id="cddays"></span> days <span id="cdhours"></span> hours <span id="cdminutes"></span> minutes <span id="cdseconds"></span> seconds </div>
<script>
// Change to meet requirements
var endtime = getEndTime();
var currentTime = null;
var clockDown = false;
updateCurrentTime();
var seconds = 1;
setInterval(function() {
if (seconds++ % 15 == 0) {
updateCurrentTime();
}
else {
currentTime += 1000;
}
clockDown += 1000;
updateCounter();
}, 1000);
// Function for demo purposes - creates an end date in the future
// so each person who visits the page can see the code working
// without having to configure a hardcoded end date
function getEndTime()
{
var future = (new Date()).getTime() + 86400000 + 3600000;
var date = new Date(future);
console.log(date.getYear());
var utc = Date.UTC(date.getYear() + 1900, date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
return utc;
}
function updateCounter()
{
var diff = (endtime - currentTime) / 1000;
var days = (diff >= 86400) ? parseInt(diff / 86400) : 0;
diff = diff - days * 86400;
var hours = parseInt(diff / 3600);
diff = diff - hours * 3600;
var minutes = parseInt(diff / 60);
seconds = diff - minutes * 60;
document.getElementById('days').innerHTML = days;
document.getElementById('hours').innerHTML = hours;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
var diff = (endtime - clockDown) / 1000;
var days = (diff >= 86400) ? parseInt(diff / 86400) : 0;
diff = diff - days * 86400;
var hours = parseInt(diff / 3600);
diff = diff - hours * 3600;
var minutes = parseInt(diff / 60);
seconds = diff - minutes * 60;
document.getElementById('cddays').innerHTML = days;
document.getElementById('cdhours').innerHTML = hours;
document.getElementById('cdminutes').innerHTML = minutes;
document.getElementById('cdseconds').innerHTML = seconds;
}
function updateCurrentTime()
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
currentTime = (new Date(this.responseText)).getTime();
if (!clockDown) {
clockDown = currentTime;
}
}
};
xhttp.open("GET", "t1991.getservertime.php", true);
xhttp.send();
}
</script>
Working sample here
I am seeing deviation of 1 second after 30 min continuous running .
@Julian: You're more patient than I am! ;-)
Deviation 1 second constant after roughly 17 hours - based on these results synch with server not necessary in this case.
You're more patient than I am! ;-)I doubt that - I have seen your teaching examples and articles ...
... up to 4 seconds deviation after 15 hours.
Browser is working hard so that obviously having an effect.
Browser is working hard so that obviously having an effect.
ASKER
Yes, there is a deviation also when the time comes to what it is expected, the countdown is coming back and not "the game"...
Not the sample above is not an embargo solution - it is merely a test I did to see how accurate setInterval is in keeping track with real time.
It needs to have a check for when currentTime <= 0 upon which it will refresh the page.
As Ray has outlined above - the responsibility lies with the server for deciding whether or not to show the embargoed page or the coutdown timer. The latter should only do the countdown and then the page refresh when counter = 0.
If you need a sample post back.
It needs to have a check for when currentTime <= 0 upon which it will refresh the page.
As Ray has outlined above - the responsibility lies with the server for deciding whether or not to show the embargoed page or the coutdown timer. The latter should only do the countdown and then the page refresh when counter = 0.
If you need a sample post back.
ASKER
it would be good please. But there is something that I am trying to modify with the code that you gave me in the previous question is that i don't need to use the day, year I only need the hour, minute and seconds so I tried by putting instead of this
var endtime = Date.UTC(2017,0,12,11,03,00);
I put this
var endtime =new DateTime('10:10:00');
This is JavaScript
That is not how it works. You need to use the full Date/Time object. This information is required for correct computation. You only need to display the fragments that you want your clients to see. Please refer back to the earlier answer:
To the issue of only time and not date, the answer is "yes, of course." Your internal application on the server will use a DateTime object, but when you format the information for browser display, you will choose the formatting that shows exactly what you want to show to the client. Please see Producing "Pretty" Dates From DateTime Objects, Computing the Difference Between DateTime Objects, and Time Without Date in this article:
https://www.experts-exchange.com/articles/20920/Handling-Time-and-Date-in-PHP-and-MySQL-OOP-Version.html
If you take an hour or two of concentrated study, to really get into that article, reading the text and experimenting with the code samples, you will have the underpinning of knowledge you need to work with Date/Time values in PHP. Of course this assumes you have the time and you want to learn this stuff! If you're not willing to put in the study time, I understand; time is money and everyone has an agenda. In that case you should consider hiring a professional developer to do the work for you. E-E Gigs offers an easy way to hire a professional for a short-term project.
var endtime = Date.UTC(2017,0,12,11,03,00);
This is part JavaScript and part PHP, inappropriately mixed togethervar endtime =new DateTime('10:10:00');
... i don't need to use the day, year I only need the hour, minute and seconds ...
That is not how it works. You need to use the full Date/Time object. This information is required for correct computation. You only need to display the fragments that you want your clients to see. Please refer back to the earlier answer:
To the issue of only time and not date, the answer is "yes, of course." Your internal application on the server will use a DateTime object, but when you format the information for browser display, you will choose the formatting that shows exactly what you want to show to the client. Please see Producing "Pretty" Dates From DateTime Objects, Computing the Difference Between DateTime Objects, and Time Without Date in this article:
https://www.experts-exchange.com/articles/20920/Handling-Time-and-Date-in-PHP-and-MySQL-OOP-Version.html
If you take an hour or two of concentrated study, to really get into that article, reading the text and experimenting with the code samples, you will have the underpinning of knowledge you need to work with Date/Time values in PHP. Of course this assumes you have the time and you want to learn this stuff! If you're not willing to put in the study time, I understand; time is money and everyone has an agenda. In that case you should consider hiring a professional developer to do the work for you. E-E Gigs offers an easy way to hire a professional for a short-term project.
You don't want to break from the UTC bit - it is necessary
Getting rid of the hour minutes and seconds is in the formatting part so you remove the following
Getting rid of the hour minutes and seconds is in the formatting part so you remove the following
var diff = (endtime - currentTime) / 1000;
// Don't account for days
//var days = (diff >= 86400) ? parseInt(diff / 86400) : 0;
//diff = diff - days * 86400;
var hours = parseInt(diff / 3600);
diff = diff - hours * 3600;
var minutes = parseInt(diff / 60);
seconds = diff - minutes * 60;
// Take out the update of the days display
//document.getElementById('days').innerHTML = days;
document.getElementById('hours').innerHTML = hours;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
We seem to have two threads running simultaneously.
I am reposting code from https://www.experts-exchange.com/questions/28993940/How-to-set-a-countdown-by-not-using-the-PC-time-in-PHP.html?anchorAnswerId=41956736#a41956736
Here is a working sample
Landing page
I am reposting code from https://www.experts-exchange.com/questions/28993940/How-to-set-a-countdown-by-not-using-the-PC-time-in-PHP.html?anchorAnswerId=41956736#a41956736
Here is a working sample
Landing page
<?php
// THIS IS A SAMPLE WE MAY WANT TO DEMONSTRATE MANY TIMES
// FOR THIS REASON WE USE A SESSION TO INITIALISE THE TARGET TIME
// 30sec IN THE FUTURE
// REAL WORLD SOLUTIONS WOULD HAVE A FIXED target
session_start();
$target = isset($_SESSION['target']) ? $_SESSION['target'] : strtotime('now + 30 seconds');
$_SESSION['target'] = $target;
// IF THE COUNTDOWN HAS NOT EXPIRED THEN LOAD THE counter PAGE
// ELSE LOAD THE game PAGE
$page = $_SESSION['target'] >= time() ? 't1991.counter.php' : 't1991.game.php';
require_once($page);
Counter Page<!doctype html>
<html>
<body>
<span id="hours"></span> hours <span id="minutes"></span> minutes <span id="seconds"></span> seconds
<script>
// INITIALISE COUNTER WITH TARGET TIME
var endtime = <?php echo $target;?> * 1000;
var currentTime = 0;
updateCurrentTime();
var seconds = 1;
setInterval(function() {
updateCounter();
if (currentTime >= endtime) {
window.location.reload();
}
if (seconds++ % 15 == 0) {
updateCurrentTime();
}
else {
currentTime += 1000;
}
}, 1000);
function updateCounter()
{
var diff = (endtime - currentTime) / 1000;
var hours = parseInt(diff / 3600);
diff = diff - hours * 3600;
var minutes = parseInt(diff / 60);
seconds = diff - minutes * 60;
document.getElementById('hours').innerHTML = hours;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
}
function updateCurrentTime()
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
currentTime = (new Date(this.responseText)).getTime();
}
};
xhttp.open("GET", "t1991.getservertime.php", true);
xhttp.send();
}
</script>
</body>
</html>
Game Page<!doctype html>
<html>
<body>
<h1>Welcome to the game page</h1>
<a href="t1991.reset.php">Reset</a>
</body>
</html>
Reset Page<?php
session_start();
unset($_SESSION['target']);
session_destroy();
header('location: t1991c.php');
Server Time Page<?php
echo gmdate("Y-m-d\TH:i:s\Z");
Working sample here
ASKER
Here is the page in my website here
index.php
counter.php
game.php
time.php
index.php
<?php
// THIS IS A SAMPLE WE MAY WANT TO DEMONSTRATE MANY TIMES
// FOR THIS REASON WE USE A SESSION TO INITIALISE THE TARGET TIME
// 30sec IN THE FUTURE
// REAL WORLD SOLUTIONS WOULD HAVE A FIXED target
session_start();
$target = isset($_SESSION['target']) ? $_SESSION['target'] : strtotime('now + 30 seconds');
$_SESSION['target'] = $target;
// IF THE COUNTDOWN HAS NOT EXPIRED THEN LOAD THE counter PAGE
// ELSE LOAD THE game PAGE
$page = $_SESSION['target'] >= time() ? 'counter.php' : 'game.php';
require_once($page);
counter.php
<!doctype html>
<html>
<body>
<span id="hours"></span> hours <span id="minutes"></span> minutes <span id="seconds"></span> seconds
<script>
// INITIALISE COUNTER WITH TARGET TIME
var endtime = <?php echo $target;?> * 1000;
var currentTime = 0;
updateCurrentTime();
var seconds = 1;
setInterval(function() {
updateCounter();
if (currentTime >= endtime) {
window.location.reload();
}
if (seconds++ % 15 == 0) {
updateCurrentTime();
}
else {
currentTime += 1000;
}
}, 1000);
function updateCounter()
{
var diff = (endtime - currentTime) / 1000;
var hours = parseInt(diff / 3600);
diff = diff - hours * 3600;
var minutes = parseInt(diff / 60);
seconds = diff - minutes * 60;
document.getElementById('hours').innerHTML = hours;
document.getElementById('minutes').innerHTML = minutes;
document.getElementById('seconds').innerHTML = seconds;
}
function updateCurrentTime()
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
currentTime = (new Date(this.responseText)).getTime();
}
};
xhttp.open("GET", "time.php", true);
xhttp.send();
}
</script>
</body>
</html>
game.php
<!doctype html>
<html>
<body>
<h1>Welcome to the game page</h1>
<a href="reset.php">Reset</a>
</body>
</html>
reset.php<?php
session_start();
unset($_SESSION['target']);
session_destroy();
header('location: index.php');
time.php
<?php
echo gmdate("Y-m-d\TH:i:s\Z");
In reset.php your probably want to use session_write_close() instead of session_destroy(). It may not make the application work, but it's strategically better to be sure the session data is written before the redirection occurs.
https://www.experts-exchange.com/articles/11909/PHP-Sessions-Simpler-Than-You-May-Think.html
https://www.experts-exchange.com/articles/11909/PHP-Sessions-Simpler-Than-You-May-Think.html
It looks like a caching issue on the time.php call
try changing your $get to
@Ray
Why not session_destroy() - the idea is to wipe it out completely so the next iteration starts fresh - did I miss a step?
try changing your $get to
xhttp.open("GET", "time.php?" + seconds, true);
@Ray
Why not session_destroy() - the idea is to wipe it out completely so the next iteration starts fresh - did I miss a step?
ASKER
$get from where ? which file ?
Not $get - the xmlhttprequest - was thinking in jQuery when I posted
xhttp.open("GET", "time.php?" + seconds, true);
ASKER
i updated it , can you try , when I reset it again the same problem comes back...
... did I miss a step?I understand the intent. I think session_write_close() exists for the purpose of "checkpointing" the session data, and that is more likely to be what we want here. The unset() is removing a specific data element from the session. This is the element we want removed. Destroying all of the session data is a bit ham-fisted and probably unnecessary. This is the man page note from session_destroy(): You do not have to call session_destroy() from usual code. Cleanup $_SESSION array rather than destroying session data.
The reason I recommend session_write_close() is detailed in the article. TL;DR session_write_close() does what we always assumed the script terminator would do for us - write and close the session. I have found this necessary after the changes at PHP 5.6 in general procedural code. I have also found this necessary when AJAX requests start one or more background scripts and the scripts interact through the session. It forces a predictable, orderly sequence of events.
OIC what you mean. Yes in a general case session_destroy() might have side effects. In this case however I don't need the session for anything else so I am killing it but I see the logic in not putting that out there as a general solution.
ASKER
Look at this code and tell me what do you think !
<body>
<div style="visibility:hidden" id="count">
<span id="hour"></span> hours <span id="minute"></span> minutes <span id="seconde"></span> seconds
</div>
<div style="visibility:hidden" id="game">
<span>yes</span>
</div>
</body>
<script src="http://code.jquery.com/jquery-1.8.2.min.js" type="text/javascript"></script>
<script>
var jsondate;
var jsonhours;
var jsonminutes;
var jsonhm;
var test;
function myCallback(json){
jsondate= new Date(json.dateString);
jsonhours = jsondate.getHours();
jsonminutes = jsondate.getMinutes();
jsonhm= jsonhours+''+jsonminutes;
}
function startTimer(duration, hour,minute,seconde) {
var timer = duration,hours, minutes, seconds;
setInterval(function () {
hours = parseInt(timer / 3600, 10)
minutes = parseInt(timer / 60 % 60, 10)
seconds = parseInt(timer % 60, 10);
hours = hours < 10 ? "0" + hours : hours;
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
hour.text(hours);
minute.text(minutes);
seconde.text(seconds);
if (--timer < 0) {
document.getElementById('game').style.visibility="visible";
document.getElementById('count').style.visibility="hidden";
}
}, 1000);
}
jQuery(function ($) {
var tenhourstenminutes = 60 *60*10+(60*10);
hour = $('#hour');
minute = $('#minute');
seconde = $('#seconde');
alert(jsonhm);
if(jsonhm >= 00 && jsonhm <= 1830)
{
document.getElementById('game').style.visibility="hidden";
document.getElementById('count').style.visibility="visible";
startTimer(tenhourstenminutes, hour,minute,seconde);
}
else
{
document.getElementById('game').style.visibility="visible";
document.getElementById('count').style.visibility="hidden";
}
});
</script>
<script type="text/javascript" src="http://www.timeapi.org/utc/now.json?callback=myCallback"></script>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Who closed this question? Given that the first comment included a tested and working code sample, it seems like the point distribution is a little off-base.
Looks like the author closed it
Maybe so. The email message I got didn't look the same as the other messages when an author closes a question, but E-E is always fiddling with its UX. Wondering if E-E has new automation for its two-week stale questions?
When the client makes a request for the Monday Game, the server will check the Date/Time value in the embargo record. If the embargo has passed, the game will be presented. If the embargo has not passed, the game will not be presented, and instead, a message telling the wait time will be presented.
If you want to "pretty this up" you might take the information from the DateInterval object $diff and send it to a client-side script in the form of a JSON string or similar. The client-side script could start a simple client-side countdown timer. There would be no need to recall the server-side script if the client-side timer is running. When the (human) client refreshes the page, the countdown timer would naturally start over with the new interval and would continue until it expires. When the countdown timer expires, the browser can be redirected to request this page again, and that request will present the "Monday Game" because the embargo date/time will have passed. If the (human) client is away when the embargo expires, that's no problem - the next request to this page will present the "Monday Game."
https://iconoun.com/demo/temp_snipercode_embargo.php
Open in new window