Skip to page content or Skip to Accesskey List.

Work

Main Page Content

Building A Quick Countdown Application

Rated 3.94 (Ratings: 4)

Want more?

  • More articles in Code
 
Picture of mwarden

Matt Warden

Member info

User since: 18 May 1999

Articles written: 7

Ever find yourself counting down the days until an event? A visit from an out-of-town friend? A trip to Chile? An

upcoming evoltageddon? I know I do this quite often. I used to spend a lot of time staring at the Windows calendar,

counting days. Then I got bored one rainy day...

The easiest way I found to write a countdown script was to break down time into the smallest unit needed. For this

script, seconds will do just fine (it's more fun to watch seconds decrement than it is to watch minutes do the same). If

you want to use milliseconds, well, it's your CPU.

The script involves two parts: one on the server side, and one on the client side (the entire thing could be

client side, but it's much simpler to rely on a single clock than it is to rely on X clocks on client computers). Here's

the basic rundown of what we have to do to create this countdown script:

  • Determine the relation between your time and the time on your server

On the server side...

  • Get the current server time in a variable
  • Store the "zero time" (the time at which the countdown should be zero based on on your server's clock!!!) in a variable
  • Find the difference, in seconds, between the current time and zero time (we'll call this iSecondsLeft for this article).
  • Set a variable to hold the remaining days. This value can be found by taking the whole integer portion only of the quotient of iSecondsLeft divided by 86,400 (60 seconds * 60 minutes * 24 hours)
  • Reassign iSecondsLeft to the result of iSecondsLeft modulus 86,400 *
  • Set a variable to hold the remaining hours. This value can be found by taking the whole integer portion only of the quotient of iSecondsLeft divided by 3,600 (60 seconds * 60 minutes).
  • Reassign iSecondsLeft to the result of iSecondsLeft modulus 3,600 *
  • Set a variable to hold the remaining minutes. This value can be found by taking the whole integer portion only of the quotient of iSecondsLeft divided by 60 (60 seconds).
  • Reassign iSecondsLeft to the result of iSecondsLeft modulus 60 *
  • You now have variables holding the remaining time broken down into days, hours, and seconds until the event.
  • Create text form fields (or other containers that may not degrade as well) and write the variables to the value attribute of each field.

* If you don't have the modulus operator available to you, you can achieve the same effect by

using multiplication and subtraction. For instance, if you needed to calculate iSecondsLeft modulus 86,400 without using the

modulus operator, you could use: iSecondsLeft - (numberOfDays * 86,400) and you will get the same value.

Now, at this point, you have enough to simply write out the remaining time. However, one second later this value will

be inaccurate. You could refresh the screen every second, but then you're putting unnecessary strain on the server. The

solution involves a balance between server and client. So, we need some scripting on the client:

On the client-side...

  • Add the function decrement() to the onLoad event handler of the <body> element

  • In the function decrement(), first check an iterations counter. If the counter is greater than 300 (or some other value determined by you), refresh the page. This ensures that the script is synched with the server clock every 300 seconds

  • If the iterations counter is below 300, decrement the seconds, taking into account the possibility that seconds are already at 0, in which case minutes have to be decremented and seconds set to 59, unless minutes are also at 0, in which case hours must be decremented and minutes have to be set to 59 and seconds have to be set to 59, and so on.

  • Finally, increment the iterations counter and set a timer to recall the function in one second (in JavaScript, you would do this by calling:
    setTimeout("decrement();", 1000);).

That's the basics. Below is an example implementation of the above idea. It is written in ASP and client-side

JavaScript.

<%@EnableSessionState = False%>

<%

Response.Expires = 0

currentTime = Now()

destinationTime = CDate("8/15/2003 14:00:00")

iTotalSeconds = DateDiff("s", currentTime, destinationTime)

iSecondsLeft = iTotalSeconds

days = Fix(iSecondsLeft / (60 * 60 * 24))

iSecondsLeft = iSecondsLeft mod (60 * 60 * 24)

hours = Fix(iSecondsLeft/(60 * 60))

iSecondsLeft = iSecondsLeft mod (60 * 60)

minutes = Fix(iSecondsLeft / (60))

iSecondsLeft = iSecondsLeft mod 60

seconds = iSecondsLeft

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01

Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html><head>

<script language="JavaScript" type="text/javascript">

<!-- hide from older browsers

iterations = 0;

function decrement()

{

if (iterations > 300)

{

window.location = '<%Response.Write Request.ServerVariables("SCRIPT_NAME")%>';

}

sec = (document.fooform.sec.value)-0;

min = (document.fooform.min.value)-0;

hrs = (document.fooform.hrs.value)-0;

day = (document.fooform.day.value)-0;

// check first to see if there is any time left at all

// this is done by adding the time units and testing

// its value

if ((sec+min+hrs+day) > 0)

{

if (sec > 0)

document.fooform.sec.value = (sec-1);

else

{

if (min > 0 )

document.fooform.min.value = min-1;

else

{

if (hrs > 0)

document.fooform.hrs.value = hrs-1;

else

{

if (day > 0)

document.fooform.day.value = day-1;

else

document.fooform.day.value = 0;

document.fooform.hrs.value = 23

}

document.fooform.min.value = 59

}

document.fooform.sec.value = 59;

}

setTimeout("decrement();", 1000);

}

else

{

document.fooform.sec.style.color = "#cc0000";

document.fooform.min.style.color = "#cc0000";

document.fooform.hrs.style.color = "#cc0000";

document.fooform.day.style.color = "#cc0000";

alert("Evolt has taken over the world!");

}

iterations++;

}

// -->

</script>

<style type="text/css">

INPUT {

font-family: Verdana, Arial, Helvetica, sans-serif;

font-size: 13px;

width: 28px;

border: none;

text-align: right;

background-color: #3399ff;

color: #003399;

font-weight: bold;

}

BODY {

font-family: Verdana, Arial, Helvetica, sans-serif;

font-size: 13px;

background-color: #3399ff;

color: #003399;

}

P {

width: 600px;

text-align: center;

}

</style>

<title>Evolt's World Domination Timeline</title>

</head>

<body onLoad="decrement();">

<form name="fooform" id="fooform" action="<%Response.Write

Request.ServerVariables("SCRIPT_NAME")%>">

<p><a href="http://evolt.org/"><img

src="/evolt/evolt_logo.gif" border="0" alt="Evolt.org

logo" longdesc="http://evolt.org/evolt_images"></a></p>

<p style="padding-top: 30px;">Assuming no one <a

href="http://www.cia.gov/" target="_new">important</a> gets tipped off, Evolt's world

domination plan will have been executed in

<%

Response.Write _

"<input type=""text"" name=""day"" value=""" & days &

"""> days, " _

& "<input type=""text"" name=""hrs"" value=""" & hours &

"""> hours, " _

& "<input type=""text"" name=""min"" value=""" & minutes

& """> minutes, and " _

& "<input type=""text"" name=""sec"" value=""" & seconds

& """> seconds."

%>

</p>

<p>

A note to those important people: <strong>I'm just kidding</strong>.

</p>

</form>

</body>

</html>

Matt Warden spends his spare time writing up author bios for his accounts on various websites... er... you know what? It's all here somewhere anyways. No use repeating myself...

The access keys for this page are: ALT (Control on a Mac) plus:

evolt.org Evolt.org is an all-volunteer resource for web developers made up of a discussion list, a browser archive, and member-submitted articles. This article is the property of its author, please do not redistribute or use elsewhere without checking with the author.