Date Countdown Timer - Pg. 2
         by senocular

The idea behind the counter is having two dates in time and finding the difference between them. At first, that may seem difficult because you would have to think that you would need to first find the difference in days, then figure into that the difference in hours and then minutes and so on. The good news is that it's not that difficult and the difference can actually be done directly on the millisecond level meaning only one calculating in difference of milliseconds needed to find the number of milliseconds between two dates. The bad news is that the days, hours, minutes etc. will still need to be figured out from those milliseconds so some tedious work will still be needed.

  1. The first step is defining your event date - or the date in time you'll be counting down to. This is done using the Date object to create a date. Be wary of the month input for your Date definition, however, as the Date object uses month values of 0 to 11 and not 1 to 12 as you may be used to. This example uses Christmas, so Christmas will be used as the date to countdown to. You can use any date you want though. Also, because the comparison between the current date and this event date is done through milliseconds, those milliseconds will need to be retrieved as well using getTime();

 
  1. Now that the eventDate has been defined, we can start running an enterFrame event to continuously countdown from the current date to that date. Because the current date is always changing, its never now for longer than it is... now, we need to keep calculating the current date (variable currentDate) and its milliseconds from getTime() on each frame so the timer can be updated accordingly. The comparison is a simple subtraction of the currentDate's milliseconds from the eventDate's milliseconds. This will be set to a msecs variable which will also provide the display of the milliseconds on the countdown timer. Since the counter movieclip has all the numbers within it, it's easiest to use it's onEnterFrame event to handle this, and in fact necessary given this approach.

  1. Next we can do a simple check to see if the eventDate has been reached. All this requires is checking to see if the msecs is a negative number. If it is, it would mean the current time is past the event time and therefore the event has been reached. If that is the case, you would want to display the result of the countdown, where here, its playing to the next frame showing the big Horah!

  1. If the date hasn't yet been reached, which will most likely be the case, then you'll need to start calculating and formatting your numbers. This means getting days, hours, minutes and seconds out of your milliseconds and making sure they fit the format of your counter. This counter uses 3 characters or digits for days, 2 for hours, 2 for minutes, 2 for seconds and 3 for milliseconds - each will have to be formatted accordingly. There are 3 steps in this process:
  1. Determine each days, hours, minutes and seconds values out of your milliseconds
     
  2. Reduce the value of each to not exceed it's expected range, i.e. hours should not go above 24 and minutes not above 60. Days can go higher since that is the highest value and expected to be high.
     
  3. Convert each value to a string and add leading 0s to make the value reach the number of digits needed to fulfill its requirement. If seconds for example is 5, it needs to become "05".

The first step is easily accomplished with division. You should already know to find out how many seconds are in 3000 milliseconds you just divide by 1000, and to get the minutes from the seconds, divide by 60.

Step number 2 is accomplished using the modulo (%) operator which takes any value and returns the remainder of a division. Take, for instance, 90 seconds. This, when divided by 60 gives you 1 for 1 minute. But there's still 30 seconds remaining. How is that retained? From a mod! If you take that 90 and mod it by 60, you'd get 30 - the remaining number of seconds or the remainder left over from a division.

The last part just means adding 0s in front of the number (as a string) if it's not long enough.

  1. Finally, at the end of the counter onEnterFrame function, run through all the movieclips in this counter movieclip (each numbers movieclip) and call the function which dissects the name of each of those clips and tells it to go to the appropriate frame based on the value of the previously defined variable it references.

What is this function you ask? It's the evaluateFrameFrom function which is the very last thing that needs to be defined for all this to work, fully implementing the trick that makes what could have been a lot of work... less. This will be made as a MovieClip.prototype so that all movieclips will inherently have access to the function whenever they want - namely, all the numbers movieclips.

  1. So, for this thing to function we need it to dissect the name of each movie as we have so cautiously and carefully preplanned and find out which number value and ultimately which frame each numbers movieclip is to display. The names, if you'll remember, are made up of the variable they use and the character in the variable they represent (a reason for making sure each value had the right number of digits). With that information we can snag the value of the variable as a string (this is the variable as its stored in the counter movieclip - its passed as an argument so that variable can be accessed from it), then use charAt and with the correct character number to find out which number it should show. Add 1 to that number and you have a frame to go to (remember 0 is on frame one, so all frames are offset by 1).

Just to further enforce what's going on here, let's do a quick example using the day_1 numbers movieclip. In looping through its movieclips, counter will eventually reach days_1 and run evaluateFrameFrom on it passing in itself (counter). days_1 is separated into an array by dividing the name by its "_" character giving "days" (nameArray[0]) and "1" (nameArray[1]). The value of days is then retrieved from the passed variableClip (counter) using associative array syntax and is set to numberset.

The value of days in variableClip would be a string something along the lines of "045". Character is then used to get which of those 3 values this movieclip is to represent. It is just nameArray[1] turned into a number or "1" to 1. So, charAt(1) of "045" would be 4. Turn that into a number and add one and you get frame 5 where the image of the 4 is located. The movieclip, days_1, is then played to that frame to show it.

 Ask Sen
Hey Sen!
How can I tell Flash to get the time from the server instead of the user's own PC? I do not want people to change their system clocks in order to "cheat" and find out what is at the end of the countdown tutorial?

Dan
 

Well Dan,
You will need to do the following:

  • Get event date in Flash

  • Get 'real' time from server

  • Every frame add to the 'real' time the change in milliseconds from when it was first received using getTimer()

  • With that new 'real' time + change in time, you have the real time as the server would see it, which can then be compared with the event time and a counter created.

Here is an example using PHP: servercountdown.zip

Though a bit tricky in some senses, you can now have a template for making countdown timers to any date! Should you want to countdown to Christmas, or maybe your birthday or even the release of a new movie, you now know how to make that happen and how to do so with your own custom images to display for numbers - and they technically don't even have to be numbers. Instead you could use 3 cows standing on top of each other to represent 3 or something even more abstract all together. The decision is yours. Have fun with it.

download source for Flash MX
download the images files for Photoshop

 

If you have any questions, feel free to post them on the forums by clicking the following link: kirupaForum.

Senocular

 

Previous Page: Graphics

 




SUPPORTERS:

kirupa.com's fast and reliable hosting provided by Media Temple.