Counting down to the end of the world
March 22, 1999
by Pat McClellan
Dear Multimedia Handyman,
I'm trying to create a countdown clock for a screensaver that looks for the year 2000 and consequently calculates how long we have left ie: 277 days : 12 hours : 13 Mins etc. I would also like to then make a sprite move along a line in accordance with the present date.
Can you help me? I'm a novice with Director 7.
Colin Usher
Dear Colin,
Glad to see you're using Director 7. That means that we can use a Lingo function that is new to D7, the systemDate. This function returns the date (as set in the user's computer) in a predictable format that is capable of math functions. For example, the systemDate will return today's date, in the format (yyyy,mm,dd). That year in 4 digits, month in 2 digits, and day in 2 digits. That means that this format does not vary between US and European displays. So, we can set a variable to the last day of this century (1999,12,31), and then subtract the systemDate to get the number of days left.
Download the code in Mac or PC format
The next step is a little more complicated because D7 does not have time functions that are as useful as the systemDate. For time, use "the long time" to return a string which contains the hour, minute and second, as well as AM or PM. For example:
put the long time -- "10:51:36 AM"
We'll need to separate the hour, minute and second from this string. It's fairly easy to do. First, I'll set "the itemDelimiter" to be the colon. Then, I can refer to the hour as "item 1 of the long time". Minutes will be item 2. Seconds is trickier because item 3 is anything after that second colon, so the AM or PM gets included. So, before setting seconds = item 3, I have to delete these last 3 chars of the time (space, + AM or PM).
With the current hour, minute and second separated out, we can do our math calculations. Since we don't know if the user is on a 12 or 24 hour clock, we'll have to check for that with the AM/PM, and whether the hour is greater than 12. So, if the time contains AM or if the hour is greater than 12, we know we're safe subtracting the hour from 23 to get hours left. Otherwise, it must be afternoon or evening, and the displayed hour is less than 12 so we're on a 12 hour clock. That means we need to subtract the current hour from 11 to get hours left (in this day.)
Minutes and seconds are much easier. Subtract the current minutes from 59 to get minutes left in this hour, and subtract the current seconds from 59 to get the seconds left in this minute. NOTE: You use 59, because you would never want to display 60 minutes left. Instead, you'd display 1 hour and 00 minutes left. Same for seconds, and 23 or 11 for days.
The final step is simply to plug the values into a field or text cast member. Here's the behavior for the countdown.
-- Millennium Countdown Behavior
-- copyright © 1999, ZZP Online, LLC
-- Free use for readers of Director Online
on exitFrame me
set daysLeft = date(1999,12,31) - the systemdate
set the itemDelimiter to ":"
set timeNow = the long time
set theHour = item 1 of timeNow
set the floatPrecision = 0
--adjust for 24 hour clock
if timeNow contains "AM" or theHour > 12 then
set hoursLeft = string(23 - theHour)
else
set hoursLeft = string(11 - theHour)
end if
if hoursLeft contains "." then delete ¬
the last char of hoursLeft
if the number of chars in hoursLeft < 2 ¬
then put "0" before hoursLeft
-- crop off the AM/PM part
set totalChars = the number of chars in timeNow
delete char (totalChars - 2) to totalChars of timeNow
set theMinute = item 2 of timeNow
set minutesLeft = string(59 - theMinute)
if minutesLeft contains "." then delete the ¬
last char of minutesLeft
if the number of chars in minutesLeft < 2 ¬
then put "0" before minutesLeft
set theSecond = item 3 of timeNow
set secondsLeft = string(59 - theSecond)
if secondsLeft contains "." then delete the last ¬
char of secondsLeft
if the number of chars in secondsLeft < 2 then ¬
put "0" before secondsLeft
-- put it into the display
put daysLeft && "days" & RETURN into member "display"
put hoursLeft && "hours" & RETURN after member "display"
put minutesLeft && "minutes" & RETURN after member "display"
put secondsLeft && "seconds" after member "display"
end
Having the pointer move across a timeline is a little tricky. The key is that you have to figure out a "factor" which converts the number of increments where the pointer could be positioned (365 in our case) into the range of pixels (146 in the case of this demo).
You'll notice that I only bother to change the pointer's position on beginSprite. That means that it won't move if you happen to be running the program when the day changes. It would only move less than a half a pixel per day anyway, so I figured that it's ok to update the position only when the sprite first appears. If you want, you could have it update on every exitFrame, but that sure seems like a waste of processing.
property pRange, pTimeLineSpriteNum, pRight, pFactor, pSprite
on getPropertyDescriptionList me
set pdlist to [:]
addprop pdlist, #pRange, [#comment:"Number of increments", ¬
#format:#integer, #default:365]
addprop pdlist, #pTimeLineSpriteNum, [#comment:"Timeline ¬
SpriteNum", #format:#integer, #default:1]
return pdlist
end getPropertyDescriptionList
on beginSprite me
set timeWidth = the width of sprite pTimeLineSpriteNum
set pFactor = timeWidth/float(pRange)
set pRight = the right of sprite pTimeLineSpriteNum
set pSprite = the spriteNum of me
set daysLeft = date(1999,12,31) - the systemdate
set the locH of sprite pSprite = pRight - (daysLeft * pFactor)
put pRight
put daysLeft
put pFactor
end
Hope that helps with your project!
Copyright 1997-2025, Director Online. Article content copyright by respective authors.