Creating a simple timer in Flex with the flash.utils.Timer class

by Peter deHaan on August 14, 2007

in ActionScript, Timer, TimerEvent

Here’s an example of a simple timer which displays minutes, seconds, and milliseconds, which I built in Flex using the flash.utils.Timer class. You can start and stop the timer using two Button controls.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<!-- http://blog.flexexamples.com/2007/08/14/creating-a-simple-timer-in-flex-with-the-flashutilstimer-class/ -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init()">

    <mx:Script>
        <![CDATA[
            import flash.utils.Timer;
            import flash.events.TimerEvent;

            private const MIN_MASK:String = "00";
            private const SEC_MASK:String = "00";
            private const MS_MASK:String = "000";
            private const TIMER_INTERVAL:int = 10;

            private var baseTimer:int;

            private var t:Timer;

            private function init():void {
                t = new Timer(TIMER_INTERVAL);
                t.addEventListener(TimerEvent.TIMER, updateTimer);
            }

            private function updateTimer(evt:TimerEvent):void {
                var d:Date = new Date(getTimer() - baseTimer);
                var min:String = (MIN_MASK + d.minutes).substr(-MIN_MASK.length);
                var sec:String = (SEC_MASK + d.seconds).substr(-SEC_MASK.length);
                var ms:String = (MS_MASK + d.milliseconds).substr(-MS_MASK.length);
                counter.text = String(min + ":" + sec + "." + ms);
            }

            private function startTimer():void {
                baseTimer = getTimer();
                t.start();
            }

            private function stopTimer():void {
                t.stop();
            }
        ]]>
    </mx:Script>

    <mx:ApplicationControlBar dock="true">
        <mx:Button label="Start timer" click="startTimer()" />
        <mx:Button label="Stop timer" click="stopTimer()" />
    </mx:ApplicationControlBar>

    <mx:Label id="counter" fontSize="96" />

</mx:Application>

View source is enabled in the following example.

Here’s a similar version using the DateFormatter class. Note that unlike the previous code, this version doesn’t include milliseconds in the output.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        layout="vertical"
        verticalAlign="middle"
        backgroundColor="white"
        creationComplete="init()">

    <mx:Script>
        <![CDATA[
            import flash.utils.Timer;
            import flash.events.TimerEvent;

            private const TIMER_INTERVAL:int = 10;

            private var baseTimer:int;

            private var t:Timer;

            private function init():void {
                t = new Timer(TIMER_INTERVAL);
                t.addEventListener(TimerEvent.TIMER, updateTimer);
            }

            private function updateTimer(evt:TimerEvent):void {
                var d:Date = new Date(getTimer() - baseTimer);
                counter.text = dateFormatter.format(d);
            }

            private function startTimer():void {
                baseTimer = getTimer();
                t.start();
            }

            private function stopTimer():void {
                t.stop();
            }
        ]]>
    </mx:Script>

    <mx:DateFormatter id="dateFormatter" formatString="NN:SS" />

    <mx:ApplicationControlBar dock="true">
        <mx:Button label="Start timer" click="startTimer()" />
        <mx:Button label="Stop timer" click="stopTimer()" />
    </mx:ApplicationControlBar>

    <mx:Label id="counter" fontSize="96" />

</mx:Application>

{ 24 comments… read them below or add one }

1 John C. Bland II August 15, 2007 at 8:01 am

Hey Peter, why didn’t you use binding on the textfield with a dateformatter instead of splitting up the string? I haven’t checked but does a dateformatter allow for seconds?

Just curious. Great blog btw!

Reply

2 peterd August 15, 2007 at 8:45 am

John,

DateFormatter does support seconds, but I don’t believe it supports milliseconds. But yes, I probably should update the post above and show the easier/better way that uses DateFormatter as it’d be significantly less code and a better approach if you didnt need millisecond accuracy.

Reply

3 Wannes March 21, 2008 at 11:46 am

Hello Peter,

I use your second example, but when I use a dateformatter like JJ:NN:SS, it always starts with 01:00:00 . Is this normal? Because my getTimer is just a few seconds…. Is this a known problem? Or do you know how I have to start with 00:00:00.

Thanks a lot! And euhm… very useful blog!!!

Reply

4 peterd March 21, 2008 at 4:30 pm

Wannes,

What about something like this:

private function updateTimer(evt:TimerEvent):void {
	var ms:Number = getTimer() - baseTimer
    var d:Date = new Date(0, 0, 0, 0, 0, 0, ms);
    counter.text = dateFormatter.format(d);
}

Peter

Reply

5 Wannes March 22, 2008 at 7:39 am

Thanks Peter!

Reply

6 David May 6, 2008 at 3:14 am

Peter,

Great Blog finding it a great help learning flex and actionscript. I was wonder if you could use the above method to display the system time on an appliction so the current user can see the date and the time? Or is there another method for that?

Thanks
David

Reply

7 David May 6, 2008 at 6:06 am

Managed to get what I was looking for with this below. It works for what I’m looking for. Not sure if its correct. Thanks for the start.

import flash.utils.Timer;
import flash.events.TimerEvent;

private const TIMER_INTERVAL:int = 10;

private var appTime:Timer;

private function startClock():void
{
    appTime = new Timer(TIMER_INTERVAL);
    appTime.addEventListener(TimerEvent.TIMER, updateTimer);
    appTime.start();
}

private function updateTimer(event:TimerEvent):void
{
    var currentDate:Date = new Date();
    dateAndTimeDisplay.text = timeDisplayFormatter.format(currentDate);
}

Cheers
David

Reply

8 Nicole May 20, 2008 at 5:28 am

How would you add hours to this?? I attempted it but my hours started out at 18:00:00?

Nicole

Reply

9 Dylan Oliver July 15, 2008 at 3:05 pm

I’m having the same problem with hours .. with 3900 (seconds) input as duration into the following function, it yields 19:05 instead of the expected 01:05:

private function getDuration(obj:Object, column:DataGridColumn): String {
    var duration: int = Objective(obj).lm ? Objective(obj).lm.video.duration*1000 : 100;
    var durationFormatter: DateFormatter = new DateFormatter();
    durationFormatter.formatString = "JJ:NN";
    return durationFormatter.format(new Date(duration));
}

Reply

10 Dylan Oliver July 15, 2008 at 4:19 pm

Figured it out: Date produces a local time, so the displayed time must be adjusted with the offset. Beware that getTimeZoneOffset() does appear to account for daylight savings time; where new Date(0).getTimeZoneOffset() returns 360, Date().getTimeZoneOffset() returns 300 as I’m now in Central Daylight Time.

private function getDuration(obj:Object, column:DataGridColumn): String {
    var tzOffset: int = new Date(0).getTimezoneOffset() * 60 * 1000;
    var duration: int = Objective(obj).lm ? Objective(obj).lm.video.duration*1000 : 100;
    var durationFormatter: DateFormatter = new DateFormatter();
    durationFormatter.formatString = "JJ:NN";
    return durationFormatter.format(new Date(duration + tzOffset));
}

Reply

11 nathan July 30, 2008 at 3:09 pm

Thank you again for your posts, VERY helpful. I was utterly confused until I found that getTimer was in flash.utils – could not figure out by reading where that function came from!

Reply

12 huy August 21, 2008 at 1:26 am
t = new Timer(TIMER_INTERVAL);

===>
1137: Incorrect number of arguments. Expected no more than 0.

Reply

13 peterd August 21, 2008 at 7:59 am

huy,

Which version of the Flex SDK, Flash Player, and OS are you using?
I’ve never seen that error before. It may be worth filing a bug at http://bugs.adobe.com/flashplayer/ .

Peter

(PS: If you post the bug number here, a few of us can vote/subscribe.)

Reply

14 JR November 12, 2008 at 5:23 am

Absolutely a super post for a beginner in Flex such as myself.

I have been able to get the sample working without any issues and am now changing it to suit my needs.

Many thanks!

Reply

15 vetarvomagla January 21, 2009 at 5:55 am

Did someone has this example with pause and resume?

Reply

16 Ana April 27, 2009 at 2:11 am

I tried with the same code. Unfortunately i too getting the same error mentioned earlier by huy.
Any solution to it. Pls find below for details.

Error is on line : t = new Timer(TIMER_INTERVAL);

Comments : Incorrect number of arguments. Expected no more than 0.

Reply

17 notzipo October 3, 2009 at 5:18 am

i got this error too.

flex builder 3

Reply

18 Peter deHaan October 3, 2009 at 7:59 am

@notzipo,

I just tried w/ Flex SDK 3.4 and wasn’t able to reproduce the error.
Which version of the Flex SDK/Flash Player are you using? And on which OS?

Peter

19 ed December 29, 2009 at 7:52 am

Try using the full class name in the calls. I was getting this same error and this worked to correct it:

change
var t:Timer;

to:
var t:flash.utils.Timer;

and change
t = new Timer(TIMER_INTERVAL);

to
t = new flash.utils.Timer(TIMER_INTERVAL);

I do not know the cause of the name collision, but this will get around it.

20 Daniel August 1, 2009 at 9:55 am

Thanks for your post. It works OK. You gave me an idea for a banner dynamic flex.

Reply

21 NXFX August 12, 2009 at 7:19 am

Thanks,

awesome for beginners, you should add an entry with an option to count down ;)

Thanks

Reply

22 Gerson September 16, 2009 at 3:27 pm

Hi, thanks for the post.

For the guys asking about the pause and resume functionality, this is the code I have added to make this work.

      private var pauseTimer:int;
 
      private function pause():void {
    	      pauseTimer = getTimer() - baseTimer;
    	      t.stop();
      }
 
      private function resume():void {
    	      var delta:int = getTimer() - baseTimer - pauseTimer;
    	      baseTimer = baseTimer + delta;
    	      t.start();
      }

This methods are called from the corresponding buttons in this way:

Hope this helps.

Regards

Reply

23 sideDoor September 27, 2009 at 6:48 pm

Thanks for this, plugged-right-in nicely!
sd

Reply

24 Giorgos January 21, 2010 at 8:09 am

For those who need to add hours
You need to add another mask var

private const HRS_MASK:String = "00";

then inside the t listener keeping peterd advice i add this

var ms:Number = getTimer() - baseTimer
var d:Date = new Date(0, 0, 0, 0, 0, 0, ms);
var hrs:String = (HRS_MASK + d.hours).substr(-HRS_MASK.length);

and at the end you need to change the TIMER_INTERVAL:int from 10 to 1000

great post, well done!

Reply

Leave a Comment

Sorry, this blog is terrible at eating HTML comments.
If you're pasting any HTML/XML/MXML code, you need to convert your < characters to &lt; and your > characters to &gt; .

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: