ArrayList, Bubble sorting and Timezones
Some title I made for this post.. The reason for this is that I wanted to do something what I tought was very simple and took me some time to do. For my "HomeTerm" project I want to have a select box with supported timezones. The first method that I used was getting all the Enum values available with the "reflector". This was very easy to do but posed a problem.. The names aren’t very descriptive. In this post I describe how I fetched all the timezone names, made a sortable type with IComparible and sorted an ArrayList with Bubble Sort.
Getting the StandardName property:
The ExtendedTimeZone type has a property called ‘StandardName‘ which hold a more human-readable timezone name. In .NET Micro Framework you can’t do a foreach on an Enum so I fetched the name the hard way by trying all posible values like this:
try {
Microsoft.SPOT.ExtendedTimeZone.SetTimeZone((TimeZoneId)x);
Debug.Print("Standard name: " + Microsoft.SPOT.ExtendedTimeZone.CurrentTimeZone.StandardName);
Debug.Print("Value: " + x.ToString());
} catch { }
}
This way all posible values are tryed and when it is a valid value is outputted to the debug output.
Sorting the Timezones retrieved:
The StandardName’s that are retrieved a far from alfabetical. So when I want to use this in my application I need to sort it. Ofcourse this could be done by hand but we are developers.. right? So to sort the retrieved timezones I made a new sortable TimeZoneInfo class:
/// Sortable TimeZone Info object
/// </summary>
public class SortableTimeZoneInfo : IComparable
{
public String NiceName;
public byte TimeZoneId;
// Constructor
public SortableTimeZoneInfo(String _NiceName, byte _TimeZoneId)
{
NiceName = _NiceName;
TimeZoneId = _TimeZoneId;
}
// Make this type sortable
public int CompareTo(object x)
{
// We can’t check 0
if (x == null) return 0;
// Check if object under test is a SortableTimeZoneInfo
if (x is SortableTimeZoneInfo)
{
// Return result for NiceNamn
return NiceName.CompareTo(((SortableTimeZoneInfo)x).NiceName);
}
else
{
// Throw Exception
throw new ArgumentException("I can only compare with SortableTimeZoneInfo");
}
}
}
Now I can sort all my TimeZones with the ArrayList.Sort command.. So I tought, this command isn’t supported on .NET Micro Framework. Not entirely strange as sorting is memory intensive. So we have to sort it for ourselfs.
Implementing Bubble Sort:
There are a number of sorting methods available like "Insertion Sort", "Cocktail Sort", "Quicksort" and one very simple basic method called "Bubble Sort". It is one of the simpelest methods. It isn’t very fast but that’s not a problem as this is a one time sort we have to do.
To implement bubble sort I added a new static method to our SortableTimeZoneInfo class:
public static SortableTimeZoneInfo[] Sort(SortableTimeZoneInfo[] List)
{
SortableTimeZoneInfo temp;
for (int pos = List.Length – 2; pos >= 0; pos–) {
for (int scan = 0; scan <= pos; scan++) {
if (List[scan].CompareTo(List[scan + 1]) > 0) {
temp = List[scan];
List[scan] = List[scan + 1];
List[scan + 1] = temp;
}
}
}
return List;
}
Wrapping everything up:
Now we have all the timezone’s and are able to sort a SortableTimeZoneInfo array we can make our program. It gets all the available timezones. Makes an SortableTimeZoneInfo[] Array from the ArrayList and sorts this. Finaly the list is written to the debug output.
{
// This will store the array list
ArrayList TimeZoneList = new ArrayList();
// Try to add TimeZones
Debug.Print("Getting Timezones..");
for (byte x = 0; x < 80; x++) {
try {
Microsoft.SPOT.ExtendedTimeZone.SetTimeZone((TimeZoneId)x);
TimeZoneList.Add(new SortableTimeZoneInfo(Microsoft.SPOT.ExtendedTimeZone.CurrentTimeZone.StandardName, x));
} catch { }
}
Debug.Print("Sorting Timezones..");
SortableTimeZoneInfo[] TimeZones = SortableTimeZoneInfo.Sort((SortableTimeZoneInfo[])TimeZoneList.ToArray(typeof(SortableTimeZoneInfo)));
Debug.Print("Outputing TimeZones..");
foreach (SortableTimeZoneInfo t in TimeZones) {
Debug.Print("’" + t.NiceName + "’ : " + t.TimeZoneId.ToString() + ",");
}
System.Threading.Thread.Sleep(-1);
}
Download the example program:
I hope this post was usefull, you can download the demo Visual Studio 2008 Solution here: MF_SortTimeZones.zip
You can iterate through timezone ids also in this way:
for (TimeZoneId id=TimeZoneId.FIRST; id<=TimeZoneId.LAST; id++)
You’re right.. I’ve overseen the FIRST and LAST id’s given.. anyway the sorting is still usefull