Solved

Javascript - counting down days

Posted on 2014-07-24
16
305 Views
Last Modified: 2014-07-29
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
0
Comment
Question by:Chris Millard
  • 9
  • 5
16 Comments
 
LVL 58

Expert Comment

by:Gary
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
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
 
LVL 17

Author Comment

by:Chris Millard
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
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
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 17

Author Comment

by:Chris Millard
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
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
 
LVL 17

Author Comment

by:Chris Millard
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Have you ever written a widget before?  It's a really different "thing" from regular programming.
0
 
LVL 17

Author Comment

by:Chris Millard
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
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
 
LVL 17

Author Comment

by:Chris Millard
Comment Utility
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
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Good luck with the project and thanks for the points, ~Ray
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
Since pre-biblical times, humans have sought ways to keep secrets, and share the secrets selectively.  This article explores the ways PHP can be used to hide and encrypt information.
The viewer will learn how to dynamically set the form action using jQuery.
HTML5 has deprecated a few of the older ways of showing media as well as offering up a new way to create games and animations. Audio, video, and canvas are just a few of the adjustments made between XHTML and HTML5. As we learned in our last micr…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now