I made code to countdown based on the result of a current timestamp that adds up to five minutes, and I can’t get the script to display the countdown from that timestamp. The code complete:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="//cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" /> <title>Hello, world!</title> <script src="//code.jquery.com/jquery-3.6.0.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script> <script type="text/javascript"> var duration = moment.duration(1646486515 * 1000, 'milliseconds'); var interval = 1000; setInterval(function(){ duration = moment.duration(duration.asMilliseconds() - interval, 'milliseconds'); $('#time').text(moment(duration.asMilliseconds()).format('h:mm:ss')); if(duration.asSeconds() <=0) { window.location.replace(window.location.pathname + window.location.search + window.location.hash); } }, interval); </script> </head> <body> <center><p><h1>Hello, world!</h1></p></center> <div class="container mb-2 my-2"> <div class="p-3 shadow-sm"> result of code: <span id="time" class="countdown">--:--</span> <?php echo '<br />NOW:'.time().'<br>+5 minutes: '.time()+300; ?> <br /> What i want is: 00:04:59 </div> </div> </body> </html>
The result: https://i.stack.imgur.com/oNBND.png
if you give “+5 minutes”, that is the sum of time() function + 300 seconds (5 minutes), you will have, for example, the date now + 5 minutes on future, but in timestamp. The intention here, is that script count 00:05:00 starting of time() now.
Advertisement
Answer
Look carefully at this line:
var duration = moment.duration(1646486515 * 1000, 'milliseconds');
How many minutes are there in 1646486515 seconds? A lot more than five! In fact, it is somewhere over 52 years, but when you format it you aren’t showing the years, months, and days, only the remaining hours, minutes, and seconds.
That’s because time()
is returning you a representation of a point in time, based on the number of seconds elapsed since midnight UTC, 1st January 1970.
In order to get the duration between that point in time and another point in time, you need to compare them. The simplest way to do that is to substract one from another. For instance, 1646486815 - 1646486515
gives you 300
, representing a duration of 300 seconds between those two points in time.
In your example, you know the duration is 300 seconds, so could just write that:
var duration = moment.duration(300 * 1000, 'milliseconds');
Or more simply:
var duration = moment.duration(300, 'seconds');
A second problem is on this line:
$('#time').text(moment(duration.asMilliseconds()).format('h:mm:ss'));
Here, we take a duration, and use it to create a “moment”, that is a specific point in time; but what point in time, and why? What we actually wanted was to format it, because the duration type doesn’t have a format
method, but it has methods to get hours, minutes, and seconds, so we can just write that ourselves:
var duration = moment.duration(300, 'seconds'); formattedDuration = duration.hours() + ':' + String(duration.minutes()).padStart(2, '0') + ':' + String(duration.seconds()).padStart(2, '0'); $('#time').text(formattedDuration);
The key here is to look at each piece in turn, not get caught up trying to put the pieces together until we have things working. Once we know we can create a duration based on a number of seconds, and format that duration, we can add in the PHP to decide how many seconds to start with. Once we have that working, we can add in the part that counts that duration down, and then the part that does something extra once it reaches zero.