A fixed countdown should count toward an absolute target date/time instead of starting again from the same number of seconds after every refresh. The server can provide the target timestamp, while JavaScript continuously calculates the remaining time in the browser.
const targetTime = new Date("2027-01-01T00:00:00+05:30").getTime();
const remaining = targetTime - Date.now();
If every page load starts with a hard-coded value such as 3600 seconds, refreshing gives the user another hour. An absolute event timestamp solves this because the remaining duration is recalculated from the same deadline.
const target = new Date("2027-01-01T00:00:00Z").getTime();
const remaining = Math.max(0, target - Date.now());
If the deadline comes from your server/database, encode it as data rather than building JavaScript source by string concatenation.
<?php
$targetIso = '2027-01-01T00:00:00+05:30';
?>
<script>
const targetIso = <?= json_encode($targetIso) ?>;
const targetTime = new Date(targetIso).getTime();
</script>
function update() {
const left = Math.max(0, targetTime - Date.now());
output.textContent = formatRemaining(left);
}
update();
const id = setInterval(update, 1000);
The deadline may come from the server, but Date.now() uses the client clock. For ordinary informational countdowns that is often acceptable. For auctions, authentication, payments, exams, or other authoritative deadlines, enforce the deadline on the server and treat the browser countdown as display only.
if (Date.now() >= targetTime) {
output.textContent = "Event has started";
clearInterval(id);
}
Also see the real-time clock.
Countdown Timer Date Reference
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.