Get hours, minutes and seconds from a number without maths operations

Today I’m gonna show you a secret ninja technique to extract hours, minutes and seconds from a number (representing an amount of seconds). In my example I will show an Actionscript code, but this can be implemented in JavaScript and maybe other languages too.
So, the scenario is the following: we have a number representing seconds and we want to know how many hours this amount of seconds contains, how many minutes and how many remaining seconds. We know that a minute is composed by 60 seconds and an hour by 60 minutes and we could write a series of maths operations in order to accomplish our objective, but there is a way far simple and fast: use the Date class!
Date class already implements all the methods we need:

  • getHours()
  • getMinutes()
  • getSeconds()

So, in order to take advantage of these useful methods, all we have to do is initialize a “fake” date using the amount of seconds we want to “split” into hours, minutes and seconds. The Date class has several OPTIONAL arguments that can be specified during its initializations, these are:

  • year
  • month
  • date (day number)
  • hours
  • minutes
  • seconds
  • milliseconds

Because theme all are optional, we can create a date object by specifying only the know arguments (in our case seconds) and by assigning null or zero to the others:


var date:Date = new Date(null, null, null, 0, 0, 9137);

Then by calling getHours, getMinutes and getSeconds we will obtain what we expect:


trace("hours: ", date.getHours()); // 2 hours
trace("minutes: ", date.getMinutes()); // 32 minutes
trace("seconds: ", date.getSeconds()); // 17 seconds

Not sure about the result? Let’s test it:

60 * 60 * 2 = 7200; (seconds contained in 2 hours)
32 * 60 = 1920; (seconds contained in 32 minutes)
7200 + 1920 + 17 = 9137; (original seconds!)

Documenting Actionscript classes which make use of AIR framework

This is just a quick post that may (I hope) help who are going to use asdoc tool to generate Actionscript documentation for AS classes which use AIR framework.

Problem:

You want to generate documentation for your package(s), but when you type asdoc command in the terminal you get a lot of errors such:

Type was not found or was not a compile-time constant: File.
Type was not found or was not a compile-time constant: Vector

…and so on

Solution:

You have to use -external-library-path option to include AIR swc, because AIR classes are located into external swc apart from Flex framework.
These files are under /sdks/{yourSDKVersion}/frameworks/libs/air/ (where “{yourSDKVersion}” is the version of Flex SDK you are using to deploy your applications) and are the following five:

  • airframework.swc
  • airglobal.swc
  • applicationupdater_ui.swc
  • applicationupdater.swc
  • servicemonitor.swc

The first 2 should be imported with -external-library-path option anytime you use AIR classes, the others are necessary only if you are using the update framework and/or serivicemonitor.

The following is an example of how to use the asdoc command with the option discussed:


./asdoc -source-path=/Users/davidezanotti/Documents/workspace/myproject/src/ -external-library-path=/Applications/Adobe\ Flex\ Builder\ 3\ Plug-in/sdks/3.3.0.4589/frameworks/libs/air/airframework.swc,/Applications/Adobe\ Flex\ Builder\ 3\ Plug-in/sdks/3.3.0.4589/frameworks/libs/air/airglobal.swc -doc-sources=/Users/davidezanotti/Documents/workspace/myproject/src/ -output=/Users/davidezanotti/Desktop/doc

The code above will succesfull generate documentation for all classes under the folder “/Users/davidezanotti/Documents/workspace/myproject/src/” to the “doc” folder on the desktop.

Actionscript Vector class initialization with a source Array

What you maybe already know:

Vector class is a powerful class introduced with flash player 10. It is fundamentally a special typed array into which all elements must be the same type and it is faster than a normal Array.

What you maybe don’t know:

It’s possible to initialize a Vector with an Array or another Vector as a source but you must use the Vector function not the class constructor. The class constructor in fact has the following signature:

Vector(length:uint = 0, fixed:Boolean = false)

Vector function instead has this:

Vector(sourceArray:Object):Vector.<T>

So, rather than using such approach:

var vector:Vector.<String> = new Vector.<String>();
vector[0] = "value1";
vector[1] = "value2";
vector[2] = "value3";
// ...and so on

We can do the following (Notice the absence of “this” keyword):

// create a vector with an inline Array as source
var vector:Vector.<String> = Vector.<String>(["v1", "v2", "v3"]);

// create a vector with an inline Vector as source
var vector2:Vector.<String> = Vector.<String>(vector);

// Testing (both trace will print the same string)
trace(vector[1]);
trace(vector2[1]);

Learning design patterns with Actionscript 3: episode 2 – Decorator pattern

The objective of the decorator pattern is to provide a way to add extra features and responsibilities to a class at runtime without to subclass it.

The classes diagram of this pattern is composed by an interface or an abstract class which will define the supertype of the class that will be extended (decorated) by one or more classes implementing the same interface and extending an abstract class which identify these as decorator classes.

A real scenario into which apply this pattern can be a cars store. A car is the base class and the accessories such dvd player, gps, air conditioning and so on, can be thought as decorators. Once decorated, the car (which has a method getPrice() which returns its cost) will get updated by accessories, so calling the getPrice() method will include the price of the “naked” car plus the price of the various accessories installed.

Let’s take a look to the classes…

package com.mycarstore {
	
    public interface IVehicle {
		
        function getPrice():Number;
        function getDescription():String;
		
    }
	
}

The interface above will be implemented by all the classes and we will treat the car as an IVehicle not a concrete Car class.
This is our simple Car class:

package com.mycarstore {
	
    public class Car implements IVehicle {
		
        public function Car() {
        }

        public function getPrice():Number {
			
            return 50000;
			
        }
		
        public function getDescription():String {
			
            return "Base car";
			
        }
		
    }
	
}

Now is time to see the decorators (in our scenario the accessories). This is the abstract Accessory class, all accessories will extend it:

package com.mycarstore {
	
    public class Accessory implements IVehicle {
		
        protected var _vehicle:IVehicle;
		
        public function Accessory(vehicle:IVehicle) {
			
            this._vehicle = vehicle;
			
        }
		
        public function getPrice():Number {
			
            return this._vehicle.getPrice();
			
        }
		
        public function getDescription():String {
			
            return this._vehicle.getDescription();
			
        }
		
    }
	
}

In Accessory we can notice that the class encapsulate an object of IVehicle which is passed to the constructor (of course since this class is abstract the object will be passed to the constructor of Accessory’s subclasses). This is the key concept of decorator pattern, all decorators keep a reference of the interface they are going to decorate and this reference is used as the base for methods business logic. Let’s see how:

package com.mycarstore {
	
    public class DVDPlayer extends Accessory {
		
        public function DVDPlayer(vehicle:IVehicle) {
			
            super(vehicle);
			
        }
		
        override public function getPrice():Number {
			
            return this._vehicle.getPrice() + 550;
			
        }
		
        override public function getDescription():String {
			
            return this._vehicle.getDescription() + ", DVD Player";
			
        }
		
    }
	
}

DVDPlayer is a concrete decorator and it uses the encapsulated IVehicle object in order to provide an extended version of the interface methods (getPrice() and getDescription()). Basically it uses first the reference methods and then it adds some other values.

To use the pattern we will first instantiate a Car object, than we will wrap it with one or more decorators:

var car:IVehicle = new Car();
				
trace("Price: " + String(car.getPrice()) + " - description: " + String(car.getDescription()));
				
car = new DVDPlayer(car);
				
trace("Price: " + String(car.getPrice()) + " - description: " + String(car.getDescription()));
				
car = new GPSSystem(car);
				
trace("Price: " + String(car.getPrice()) + " - description: " + String(car.getDescription()));

The output will be:

Price: 50000 - description: Base car
Price: 50550 - description: Base car, DVD Player
Price: 50875 - description: Base car, DVD Player, GPS System

The order into which we wrap the concrete component (Car) is indifferent (we can add GPSSystem before or after DVDPlayer) and of course despite its readability, we can wrap the Car in a single statement:

var car2:IVehicle = new GPSSystem(new DVDPlayer(new Car()));

In this example I used very simple classes, however in a real implementation we can create more sophisticated decorators which will accept extra arguments beyond the IVehicle reference.

parseInt(): difference between Javascript and Actionscript

Today is the day of the little big discoveries. I realized that the parseInt() function, which objective is the same in both languages (Actionscript and Javascript), is a bit different between them. In Actionscript the function is based on base 10 numeration, in Javascript instead the funny thing is that it try to guess the radix by analyzing the string received as first argument, so if you want to be sure of the result returned you have to explicitly pass the radix in the second argument.

Example:

var myString = "000123";
alert(parseInt(myString));

The code above will alert 83 instead of 123 (because the default base guessed by Javascript isn’t 10 like in Actionscript), to get 123 the code must be:

var myString = "000123";
alert(parseInt(myString, 10));