Javascript - counting down days

I found some JavaScript code for a countdown timer, which I have modified to the code shown below since I only want to count down the number of days until an event.

I am in the British Summertime time zone (currently GMT +1). How can I modify my code so that:-

1) It takes the time from a reliable source rather than the client PC (if even possible) and
2) If the browser window is left open, the JavaScript will automatically refresh when the clock passes midnight - so that the countdown decreases by 1 day?

<script type="text/javascript">
today = new Date();
BigDay = new Date("July 26, 2015");
msPerDay = 24 * 60 * 60 * 1000 ;
timeLeft = (BigDay.getTime() - today.getTime());
e_daysLeft = timeLeft / msPerDay;
daysLeft = Math.floor(e_daysLeft);
if (daysLeft < 0) daysLeft = 0;
document.write("<center>26TH JULY 2015 |<strong> " + daysLeft + " </strong> DAYS TO GO</span></center>");
</script>

Open in new window


Failing this, is there a better way?

Thanks
LVL 17
Chris MillardAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

GaryCommented:
If all you are showing is the number of days then just use a server side language, that way the time will always be consistent with the server time.
You could also add in a meta refresh - calculate how many seconds left til midnight and put this in the meta refresh tag.
Seems the simplest solution - cannot see any need for using js to do this.
0
Ray PaseurCommented:
a reliable source rather than the client PC
Your other source is the server.  Do you have a scripting language like PHP available to you?
If the browser window is left open, the JavaScript will automatically refresh when the clock passes midnight ...
Nobody designs web applications like that.  Can you please tell us in non-technical, business terms what you're trying to achieve?
0
Chris MillardAuthor Commented:
This is a countdown timer to go into a WordPress widget. There are plenty of timer widgets available that countdown the number of weeks, days, hours, minutes and seconds to an event - but they are too "fancy" for my needs - too much information, fancy boxes etc. I want a simple text display.

I am organising an event, and in the header of the website, I simply want to show the number of days to the event. I would like the countdown timer to get the correct date and time from the server (and set that to my time zone - BST) so that even if the end users device date and time is incorrect, that the countdown remains correct.
0
Determine the Perfect Price for Your IT Services

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden with our free interactive tool and use it to determine the right price for your IT services. Download your free eBook now!

Ray PaseurCommented:
in the header of the website, I simply want to show the number of days to the event
Now it makes more sense.  The part about changing at midnight is kind of quirky because of the nature of the HTTP client/server relationship.  If you want to explore that, this article describes how it works.
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/A_11271-Understanding-Client-Server-Protocols-and-Web-Applications.html

Basically, servers make requests and clients make responses.  And that's all.  Once the response is sent, the server disconnects and "goes away" while the response document remains on the client screen.  If the client does not make another request, the server cannot make another response.  So it doesn't matter how much time has passed, the client browser will still be displaying the information from the most recent response, even if the response was from three days ago.  I don't know anyone who keeps a browser window open for three days, but there you have it.

You can get around this limitation with AJAX, which causes the browser to make repeated requests.  The triggered responses can be used to modify the contents of a <div> or similar on the document.  This makes it look like the server is sending data spontaneously.  You could have a countdown timer that worked through this mechanism.

I'll see if I can find an example that shows the bare-bones moving parts.  If I can come up with something, I'll post the code here.  You might find part of the answer in Practical Application #3 of this article:
http://www.experts-exchange.com/Programming/Languages/Scripting/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html
0
Ray PaseurCommented:
Here's the "backend" script that would run on the server.  Next, we will need a little jQuery to hook it into a web page.  Take a look at line 7.  This lets you put the date into the URL argument "d=" if you want a little more flexibility.  Any reasonable format for the date will work, but I recommend only the ISO-8601 format in the URL request argument.

<?php // demo/temp_chris_millard.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Web_Development/Blogs/WordPress/Q_28482986.html

// THE DATE OF THE EVENT
$future = empty($_GET['d']) ? 'July 26, 2015' : date('c', strtotime($_GET['d']));

// THE LOCAL TIMEZONE FOR THE EVENT
$new_tz = 'Europe/London';

// SAVE SERVER'S OLD TIME ZONE AND SET THE NEW TIMEZONE
$old_tz = date_default_timezone_get();
date_default_timezone_set($new_tz);

// MAKE CURRENT AND NEW TIMESTAMPS
$a = time();
$z = strtotime($future);

// COMPUTE ELAPSED DAYS http://php.net/manual/en/function.gregoriantojd.php
$a_jd = GregorianToJD( date('m', $a), date('d', $a), date('Y', $a) );
$z_jd = GregorianToJD( date('m', $z), date('d', $z), date('Y', $z) );
$days = $z_jd - $a_jd;
if ($days < 0) $days = 0;

// FORMAT AND WRITE THE ELAPSED DAYS (MAYBE ADD MARKUP HERE)
$days_printable = number_format($days,0);
if ($days < 2) $days_printable = '<span style="color:orange;">' . $days_printable . '</span>';
echo $days_printable;

// RESTORE THE TIMEZONE
date_default_timezone_set($old_tz);

Open in new window

0
Ray PaseurCommented:
Here's another variant of the backend script, with a little more control over the message.  Example:
http://iconoun.com/demo/temp_chris_millard.php?f=dh

<?php // demo/temp_chris_millard.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Web_Development/Blogs/WordPress/Q_28482986.html

// THE DATE OF THE EVENT ** MIGHT WANT TO INCLUDE THE TIME OF DAY **
$future = empty($_GET['d']) ? 'July 26, 2015' : $_GET['d'];
$format = empty($_GET['f']) ? 'DHM'           : $_GET['f'];

// THE LOCAL TIMEZONE FOR THE EVENT
$new_tz = 'Europe/London';

// SAVE SERVER'S OLD TIME ZONE AND SET THE NEW TIMEZONE
$old_tz = date_default_timezone_get();
date_default_timezone_set($new_tz);

// COMPUTE ELAPSED (CHECK FORMATTING)
$lapse = elapsed($future, $format);

// FORMAT AND WRITE THE ELAPSED DAYS (MAYBE ADD MARKUP HERE)
echo $lapse;

// RESTORE THE TIMEZONE
date_default_timezone_set($old_tz);


// A FUNCTION TO COMPUTE AND FORMAT A MESSAGE ABOUT ELAPSED TIME
function elapsed($then, $wdhms='WDHMS', $return_array=FALSE)
{
    // TIME CONSTANT VALUES (MONTHS AND YEARS ARE OMITTED - NOT FIXED VALUES)
    $seconds_per["W"] = 60*60*24*7;
    $seconds_per["D"] = 60*60*24;
    $seconds_per["H"] = 60*60;
    $seconds_per["M"] = 60;
    $seconds_per["S"] = 1;

    // TIME DESCRIPTIVE TERMS - YOU CAN USE SOME OR ALL OF THESE
    $terms["W"] = 'week';
    $terms["D"] = 'day';
    $terms["H"] = 'hour';
    $terms["M"] = 'minute';
    $terms["S"] = 'second';

    // SET THE FLAGS FOR OUTPUT
    if (empty($wdhms)) $wdhms = 'WDHMS';
    $wdhms = strtoupper($wdhms);
    $wdhms = str_split($wdhms);
    $wdhms = array_combine($wdhms, $wdhms);

    // SET THE FUTURE/PAST TIMESTAMP OR FAIL ON ERROR
    if (!$other_timestamp = strtotime($then)) return FALSE;

    // SET THE CURRENT TIMESTAMP
    $current_timestamp = time();

    // COMPUTE THE DIFFERENCE IN SECONDS
    $lapsed_seconds    = $other_timestamp - $current_timestamp;
    if ($lapsed_seconds == 0) return 'RIGHT NOW!';

    // DETERMINE FUTURE OR PAST
    $since_until = "until";
    if ($lapsed_seconds < 0)
    {
        $since_until = "since";
        $lapsed_seconds = abs($lapsed_seconds);
    }

    // COMPUTE THE INCREMENTS
    foreach ($seconds_per as $key => $secs)
    {
        if (array_key_exists($key, $wdhms))
        {
            $lapsed_time    = floor($lapsed_seconds / $secs);
            $lapsed_seconds = $lapsed_seconds - ($lapsed_time * $secs);
            $wdhms[$key]    = (int)$lapsed_time;
        }
    }

    // RETURN AN ARRAY
    if ($return_array) return $wdhms;

    // RETURN A RESPONSE STRING
    $s = NULL;
    foreach ($terms as $key => $str)
    {
        // RETURN ONLY THE UNITS THAT WERE REQUESTED IN $wdhms
        if (!array_key_exists($key, $wdhms)) continue;
        $s
        .= ' '
        . $wdhms[$key]
        . ' '
        . $str
        ;
        if ($wdhms[$key] != 1) $s .= 's';
        $s .= ',';
    }

    // TIDY UP THE RETURN STRING AND SHOW UNTIL OR SINCE
    $s = rtrim($s, ',');
    $s .= " $since_until $then";
    $s = trim($s);
    return $s;
}

Open in new window

0
Ray PaseurCommented:
Here's a front-end script that places the countdown timer in a <div> on the web page.  It would need to be slimmed down a bit to integrate it into a WordPress Widget, but all the essential moving parts are here.  You can see the countdown timer working here:
http://iconoun.com/demo/temp_chris_millard_client.php

Caution: With one-second updates, and potentially lots of open web pages shooting repeated requests at your server, you may find that this loads the server unnecessarily.  If you wanted to change from one-second to one-minute updates -- and I recommend that you do -- make these modifications:

Line 26 change f=dhms to f=dhm
Line 35 change 1000 to 60000

<?php // demo/temp_chris_millard_client.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Web_Development/Blogs/WordPress/Q_28482986.html#a40222425

// AN EMPTY TAG FOR THE LOCATION OF OUR TIMER
$countdown_timer_html = <<<EOD
<div id="countdown_timer"></div>
EOD;

// CREATE OUR WEB PAGE IN HTML5 FORMAT
$htm = <<<HTML5
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 Page in UTF-8 Encoding, Countdown Timer</title>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

<script>
// FUNCTION TO LOAD THE TIMER
function countdown_timer_loader(){
	$("#countdown_timer").load("temp_chris_millard.php?f=dhms");
}

// JQUERY ON PAGE LOAD / DOCUMENT READY LOAD THE TIMER
$(document).ready(function(){
    countdown_timer_loader();
});

// SET INTERVALS IN MILLISECONDS TO REPEAT THE FUNCTIONS
var loader = setInterval(function(){ countdown_timer_loader(); }, 1000);
</script>

<style type="text/css">
#countdown_timer{
    font-family:verdana, sans-serif;
    font-size:small;
}
</style>

</head>
<body>

$countdown_timer_html

</body>
</html>
HTML5;

// RENDER THE WEB PAGE
echo $htm;

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Chris MillardAuthor Commented:
Wow - thanks for all the help there Ray! The backend scripts work a treat. I'll need to look more closely into the last post. If I were to use this, do you think the whole page would reload or just the contents of the widget?
0
Ray PaseurCommented:
Only the contents of the widget (technically, the <div>) will reload.  See the new version here:
http://iconoun.com/demo/temp_chris_millard_client.php

<?php // demo/temp_chris_millard_client.php
error_reporting(E_ALL);

// SEE http://www.experts-exchange.com/Web_Development/Blogs/WordPress/Q_28482986.html#a40222425

// THE CURRENT DATE AND TIME
$xyz = date('r');

// AN EMPTY TAG FOR THE LOCATION OF OUR TIMER
$countdown_timer_html = <<<EOD
<div id="countdown_timer"></div>
EOD;

// CREATE OUR WEB PAGE IN HTML5 FORMAT
$htm = <<<HTML5
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5 Page in UTF-8 Encoding, Countdown Timer</title>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>

<script>
// FUNCTION TO LOAD THE TIMER
function countdown_timer_loader(){
	$("#countdown_timer").load("temp_chris_millard.php?f=dhms");
}

// SET INTERVALS IN MILLISECONDS TO REPEAT THE FUNCTIONS
var loader = setInterval(function(){ countdown_timer_loader(); }, 1000);
</script>

<style type="text/css">
#countdown_timer{
    font-family:verdana, sans-serif;
    font-size:small;
}
</style>

</head>
<body>
<p>This is the rest of the page content.  It does not change: $xyz</p>

$countdown_timer_html

</body>
</html>
HTML5;

// RENDER THE WEB PAGE
echo $htm;

Open in new window

0
Chris MillardAuthor Commented:
Hi Ray, I can't get this working in a widget for some reason. I see the text which reads "This is the rest of the page content.  It does not change: (the date)" but not the countdown timer.
0
Ray PaseurCommented:
Have you ever written a widget before?  It's a really different "thing" from regular programming.
0
Chris MillardAuthor Commented:
It's my first widget although with the help of your earlier posts along with some other searching on Google, I have it all working - with the exception of the live countdown.

I'll look more into it tomorrow, but what I am thinking is - When the widget loads and gets the current date and time, I'll subtract that time from midnight, and I'll set that as the timer interval (or something alone those lines).
0
Ray PaseurCommented:
I think we will need to see all of the code, including the live implementation, rather than the narrative.  Something like this has got a lot of moving parts with technically detailed subsets!
0
Chris MillardAuthor Commented:
Thanks for all the help Ray. I'm going to award points based on the PHP code you gave me for replacing the JavaScript that I was using.

However, I'm temporarily "giving up" on the idea of having the code refresh at midnight as I have other parts of the website that need my attention.
0
Ray PaseurCommented:
Good luck with the project and thanks for the points, ~Ray
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
WordPress

From novice to tech pro — start learning today.