Chris Millard
asked on
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?
Failing this, is there a better way?
Thanks
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>
Failing this, is there a better way?
Thanks
a reliable source rather than the client PCYour 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?
ASKER
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.
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.
in the header of the website, I simply want to show the number of days to the eventNow 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.
https://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:
https://www.experts-exchange.com/Programming/Languages/Scripting/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html
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);
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
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;
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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?
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
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;
ASKER
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.
Have you ever written a widget before? It's a really different "thing" from regular programming.
ASKER
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).
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).
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!
ASKER
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.
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.
Good luck with the project and thanks for the points, ~Ray
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.