What we want to do is create an expression that will work as a universal clock. It should be able to display hours, minutes, seconds, and milliseconds. We want to be able to easily set the starting time, the counting speed, whether it counts up or down, and how many digits of milliseconds to display. It would also be nice to be able to have a negative sign ("-") show up if the clock time becomes less than zero. The expression should be easily editible so that if we, for example, don't want hours to display, the code change is easy to make.

The most reasonable approach will be to develop an expression for the source text property of a text layer. In that expression we'll calculate the different components (hours, minutes, seconds, and milliseconds) that represent the current time of our clock. At the beginning of the expression we'll define two variables, rate and clockStart. The variable rate will be a multiplier for how fast our clock counts compared to real, or comp, time. So if we want it to count at the same rate as a wall clock, we'd just set it to one. Since rate is a multiplier, if we set its value negative, the clock will count down.

The variable clockStart will represent the starting time of our clock. Since time values in After Effects are always represented as seconds, that's what we'll use here. Otherwise, if we defined clockStart as a string like "00:00:00.000", we'd just have to write code to convert it to seconds anyway.

For each of the hours, minutes, and seconds components, we'll run them through a function (we'll call it padZero()) which will convert the value to a string and add a leading zero if necessary. That way we'll end up with a two digit string for each component. We'll handle milliseconds a little differently, taking advantage of the built-in JavaScript function toFixed(), which is used to convert a number to a string with a fixed number of decimal places.

Finally, we'll set up the expression so that the last line is where all the parts get assembled into the final output string. This makes it easy, for example, to eliminate the hours component from the output just by removing it from the line.


rate = -2;
clockStart = 3604.999;
 
function padZero(n){
  return (n < 10 ? "0" : "") + n;
}
 
clockTime = clockStart + rate*(time - inPoint);
 
if (clockTime < 0){
  sign = "-";
  clockTime = -clockTime;
}else{
  sign = "";
}
 
t = Math.floor(clockTime);
hr = Math.floor(t/3600);
min = Math.floor((t%3600)/60);
sec = Math.floor(t%60);
ms = clockTime.toFixed(3).substr(-3);
sign + padZero(hr) + ":" + padZero(min) + ":" + padZero(sec) + "." + ms

Universal clock expression set to start at 01:00:04.999 and count down at the rate of two seconds for every one second of comp time.

Note that for best results, you'll want to use a mono spaced font (meaning that each character is the same width) so that the width of the display doesn't jump around. Lucida Console was used for this example.