Ever find yourself counting down the days until an event? A visit from an out-of-town friend? A trip to Chile? Anupcoming 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 thisscript, seconds will do just fine (it's more fun to watch seconds decrement than it is to watch minutes do the same). Ifyou 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 beclient side, but it's much simpler to rely on a single clock than it is to rely on X clocks on client computers). Here'sthe 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 byusing multiplication and subtraction. For instance, if you needed to calculate iSecondsLeft modulus 86,400 without using themodulus 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 willbe inaccurate. You could refresh the screen every second, but then you're putting unnecessary strain on the server. Thesolution 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-sideJavaScript.<%@EnableSessionState = False%><%Response.Expires = 0currentTime = 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 60seconds = 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 browsersiterations = 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 valueif ((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.WriteRequest.ServerVariables("SCRIPT_NAME")%>"><p><a href="http://evolt.org/"><img
src="/evolt/evolt_logo.gif" border="0" alt="Evolt.orglogo" 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 worlddomination 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>