Search code examples
javascriptphpjquerydatecountdown

Recurring Countdown Timer for every 18h with specific start date


I have a small fan website dedicated to a certain game. Now in that game there are two live events that reset after some period of time. First one resets every 18h and the other one resets every week (on the same day at the same time). I have been working on a script to put on the site to show when the next event reset is. I have made it work for the most part:

timer.html

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="timer.js" type="text/javascript"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</head>
<body>

<div id="daily">
  <p ></p>
</div>

<div id="weekly">
  <p ></p>
</div>

</body>
</html>

style.css

@import url(http://fonts.googleapis.com/css?family=Lato:100,400);
#daily, #weekly {
  background: #333;
  font-family: 'Lato', sans-serif;
  text-align: center;
  color: #eee;
  text-shadow: 1px 1px 5px black;
  padding: 1rem 0;
  font-size: 3rem;
  border: 1px solid #000;
}

timer.js

setInterval(function time(){

// Get strating and current date
var startDate = new Date("January 7, 2016 07:00:00");
var currentDate = new Date();

// Calcualte time passed since the start
var timePassed = currentDate.getTime() - startDate.getTime();
var convertToSeconds = Math.floor(timePassed / 1000 );
var convertToMinutes = Math.floor(convertToSeconds / 60);
var convertToHours = Math.floor(convertToMinutes / 60);
var convertToDays = Math.floor(convertToHours / 24);

// Calculate time since last daily (18h) reset
var lastResetSeconds = convertToSeconds % 60;
var lastResetMinutes = convertToMinutes % 60;
var lastResetHoursDaily = convertToHours % 18;

// Calculate time since last weekly (7d) reset
var lastResetHoursWeekly = convertToHours % 24;
var lastResetDay = convertToDays % 7;

// Calculate remaining time until next daily (18h) reset
var remainingSeconds = 59 - lastResetSeconds;
var remainingMinutes = 59 - lastResetMinutes;
var remainingHoursDaily = 17 - lastResetHoursDaily;

// Calculate remaining time until next weekly (7d) reset
var remainingHoursWeekly = 23 - lastResetHoursWeekly;
var remainingDays = 6 - lastResetDay;

// If any of the variables is only a single digit number, then add 0 before
if((remainingSeconds + '').length == 1){
  remainingSeconds = '0' + remainingSeconds;
}
if((remainingMinutes + '').length == 1){
  remainingMinutes = '0' + remainingMinutes;
}
if((remainingHoursDaily + '').length == 1){
  remainingHoursDaily = '0' + remainingHoursDaily;
}
if((remainingHoursWeekly + '').length == 1){
  remainingHoursWeekly = '0' + remainingHoursWeekly;
}
if((remainingDays + '').length == 1){
  remainingDays = '0' + remainingDays;
}

// Print
jQuery('#daily p').html(remainingHoursDaily+':'+remainingMinutes+':'+remainingSeconds)
jQuery('#weekly p').html(remainingDays+':'+remainingHoursWeekly+':'+remainingMinutes+':'+remainingSeconds)
}, 1000);

Timezone Problem

JS calculates client side time and not server side and this is a problem. This is an event that started on a certain date at certain time in PDT zone, and has restarted itself every 18h. So when I view this page I get time calculated from starting and current date BUT from my timezone and not the one from the server.

What I'm looking for here is that starting date and current date are used from server and not the client. Now, I'm aware that JS is client side run, so what I need is a workaround.

I then attempted something with php which resulted in same problem as remaining time seems to be far off. To add further to the list of problems, the jQuery no longer counts down, instead it just shows remaining time it got while loading script/page.

timer.php

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
</head>
<body>
<?php

    date_default_timezone_set('America/Los_Angeles');
    $rawDateStart = date('F j, Y H:i:s', date_timestamp_get(DateTime::createFromFormat('F j, Y H:i:s', 'January 7, 2016 07:00:00')));
    $rawDateCurrent = date('F j, Y H:i:s');
?>

<script>
setInterval(function time(){

    // Get strating and current date
    //var startDate = new Date("January 7, 2016 07:00:00");
    //var currentDate = new Date();
    var startDate = new Date("<? echo $rawDateStart; ?>");
    var currentDate = new Date("<? echo $rawDateCurrent; ?>");

    // Calcualte time passed since the start
    var timePassed = currentDate.getTime() - startDate.getTime();
    var convertToSeconds = Math.floor(timePassed / 1000 );
    var convertToMinutes = Math.floor(convertToSeconds / 60);
    var convertToHours = Math.floor(convertToMinutes / 60);
    var convertToDays = Math.floor(convertToHours / 24);

    // Calculate time since last daily (18h) reset
    var lastResetSeconds = convertToSeconds % 60;
    var lastResetMinutes = convertToMinutes % 60;
    var lastResetHoursDaily = convertToHours % 18;

    // Calculate time since last weekly (7d) reset
    var lastResetHoursWeekly = convertToHours % 24;
    var lastResetDay = convertToDays % 7;

    // Calculate remaining time until next daily (18h) reset
    var remainingSeconds = 59 - lastResetSeconds;
    var remainingMinutes = 59 - lastResetMinutes;
    var remainingHoursDaily = 17 - lastResetHoursDaily;

    // Calculate remaining time until next weekly (7d) reset
    var remainingHoursWeekly = 23 - lastResetHoursWeekly;
    var remainingDays = 6 - lastResetDay;

    // If any of the variables is only a single digit number, then add 0 before
    if((remainingSeconds + '').length == 1){
      remainingSeconds = '0' + remainingSeconds;
    }
    if((remainingMinutes + '').length == 1){
      remainingMinutes = '0' + remainingMinutes;
    }
    if((remainingHoursDaily + '').length == 1){
      remainingHoursDaily = '0' + remainingHoursDaily;
    }
    if((remainingHoursWeekly + '').length == 1){
      remainingHoursWeekly = '0' + remainingHoursWeekly;
    }
    if((remainingDays + '').length == 1){
      remainingDays = '0' + remainingDays;
    }

    // Print
    jQuery('#daily p').html(remainingHoursDaily+':'+remainingMinutes+':'+remainingSeconds)
    jQuery('#weekly p').html(remainingDays+':'+remainingHoursWeekly+':'+remainingMinutes+':'+remainingSeconds)
}, 1000);
</script>

<div id="daily"><p ></p></div>
<div id="weekly"><p ></p></div>

</body>
</html>

So I'm stuck and without any ideas how to proceed. Any pointers would be welcome. I'm honestly having hard time with time / date stuff.


Solution

  • You were close. The problem is that you are using the same value for currentDate every time your setInterval() handler runs. So even though the computation is being done once every second, the output never changes, so it appears to do nothing.

    I've fixed that issue by incrementing the currentDate var by 1 second each time the setInterval() handler runs. I'v also cleaned up your code a bit.

    This is untested, but assuming your date computations are correct, this should yield the desired output:

    <!DOCTYPE html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" href="style.css">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    </head>
    <body>
    <?php
    
        date_default_timezone_set('America/Los_Angeles');
        $rawDateStart = date('F j, Y H:i:s', date_timestamp_get(DateTime::createFromFormat('F j, Y H:i:s', 'January 7, 2016 07:00:00')));
        $rawDateCurrent = date('F j, Y H:i:s');
    ?>
    
    <script>
        var printSeconds, printMinutes, printHoursDaily, printHoursWeekly, printDays;
    
        // Get strating and current date
        var startDate = new Date("<? echo $rawDateStart; ?>");
        var currentDate = new Date("<? echo $rawDateCurrent; ?>");
    
        $(function(){    
    
            function calculateTime()
            {
                // Increment current time
                currentDate.setSeconds(currentDate.getSeconds() + 1);
    
                // Calcualte time passed since the start
                var timePassed = currentDate.getTime() - startDate.getTime();
                var secondsSinceStart = Math.floor(timePassed / 1000 );
                var minutesSinceStart = Math.floor(secondsSinceStart / 60);
                var hoursSinceStart = Math.floor(minutesSinceStart / 60);
                var daysSinceStart = Math.floor(hoursSinceStart / 24);
    
                // Calculate time since last daily (18h) reset
                var dailySecondsElapsed = secondsSinceStart % 60;
                var dailyMinutesElapsed = minutesSinceStart % 60;
                var dailyHoursElapsed = hoursSinceStart % 18;
    
                // Calculate time since last weekly (7d) reset
                var weeklyHoursElapsed = hoursSinceStart % 24;
                var weeklyDaysElapsed = daysSinceStart % 7;
    
                // Calculate remaining time until next daily (18h) reset
                var remainingSeconds = 59 - dailySecondsElapsed;
                var remainingMinutes = 59 - dailyMinutesElapsed;
                var remainingHoursDaily = 17 - dailyHoursElapsed;
    
                // Calculate remaining time until next weekly (7d) reset
                var remainingHoursWeekly = 23 - weeklyHoursElapsed;
                var remainingDays = 6 - weeklyDaysElapsed;
    
                // If any of the variables is only a single digit number, then add 0 before
                printSeconds = (remainingSeconds > 9) ? remainingSeconds : '0' + remainingSeconds;
                printMinutes = (remainingMinutes > 9) ? remainingMinutes : '0' + remainingMinutes;
                printHoursDaily = (remainingHoursDaily > 9) ? remainingHoursDaily : '0' + remainingHoursDaily;
                printHoursWeekly = (remainingHoursWeekly > 9) ? remainingHoursWeekly : '0' + remainingHoursWeekly;
                printDays = (remainingDays > 9) ? remainingDays : '0' + remainingDays;
            }
    
            setInterval(function() {
                calculateTime();
    
                // Print
                jQuery('#daily p').html(printHoursDaily+':'+printMinutes+':'+printSeconds)
                jQuery('#weekly p').html(printDays+':'+printHoursWeekly+':'+printMinutes+':'+printSeconds)
            }, 1000);
        });
    </script>
    
    <div id="daily"><p ></p></div>
    <div id="weekly"><p ></p></div>
    
    </body>
    </html>