The Yearly Countdown
End of year, December 31st. Every year millions of families world-wide gather round the tv-set just before midnight to watch the clock tick tick tick away the final seconds of the year. The clock strikes twelve and we yell “Happy New Year!” while outside fireworks burst, lighting up the sky.
It’s about time
For some years already I run a desktop widget that counts down the year. I made it with Dashcode when I was just messing around on a boring January day. After nearly a year, I found an interesting bug: it started counting up in the next year..! Just like a regular clock does.
Anyway, it’s fun saying things like “99 days left!” out of the blue and see people reacting “what was that all about?”.
The year 2012 had a leap second so there was another bug: it was off by a second. This was totally unnecessary had I implemented it properly … Just saying that dealing with time can be tricky.
Two minutes to midnight
Counting down the days until year+1 Jan 1 00:00:00 is fun and not hard to do. Be mindful though that the naive implementation of doing sleep(1)
in a loop is plain wrong. You will find your family and friends yelling out Happy New Year a split second before the counter reaches zero. Why is that? The thing is, you forgot about milliseconds, microseconds, and nanoseconds. This is illustrated by the following timeline:
23:59:56.852 countdown program start
sleep 1
23:59:57.852 sleep 1
23:59:58.852 sleep 1
23:59:59.852 sleep 1
00:00:00.000 Happy New Year! on tv
00:00:00.852 countdown program reacts too late
Here, the program starts at an offset of 852 milliseconds causing it to react too late; it practically misses the strike of midnight. 852 milliseconds feels like almost a full second, so the countdown program just isn’t good enough.
A better way to do it is to use either usleep()
or nanosleep()
to sleep fractions of a second and round it off to an (near) exact tick of a second.
Sleep with one eye open
Although you can do nanosecond sleeps, the practical accuracy of your software clock is about 15 milliseconds. This is because of timeslicing in multitasking operating systems. Really? Well, yes and no. Modern computers have a High Precision Event Timer (HPET) that can be used to do more accurate timing of events. This is entirely meant for doing things like performance measurements and not so much for wallclock time keeping.
No time to waste
A countdown timer is pretty neat and not so hard to write. It gets more fun when you add a big LED display in OpenGL graphics. I suppose it’s too late now to get it approved in the App store and get rich before 2014 starts, but we can always try again next year.
Best wishes! and if you want to read more about high precision timing, see this excellent blog post by another code monkey:
High-performance Timing on Linux / Windows