Worldclock Application
February 27th, 2008
Due the fact that I sometimes chat in IRC channels (like #cpp, #wxWidgets or #xlib) I have to deal with people located almost everywhere in the world. I mentioned that no just my time of day hanging around in IRC are curious also their times are often kinda strange.
For better understanding when they’re available I needed a worldclock.
There are dozens of worldclock implementations on the Internet but most of them were contrary to my expectations.
That’s the reason why I on the spot decited to code my own. I mean the solution I coded is worth looking at ’cause it is without any complexity and has just as little numbers of code as possible.
Of course if I would have done a console application I used needed two or three lines of code.
For example in Perl this would have been very easy:
#!/usr/local/bin/perl @timeData = localtime(time);
and then pass add/subtract the gmt difference and convert it to date again. Finally you just have to print it.
It was my intention to create at least a tiny graphical user interface for some user friendliness. I decited to do a WinForms GUI, I also could have done it with MFC or WxWidgets but maybe I’ll port it sometimes to WPF.
This is what it looks like:

Let’s have a look behind.
I created a window, a groupBox, two labels and a combobox for the selection of the country.
All timeszones are stored in an xml file:
<?xml version="1.0" standalone="yes" ?> <Countries> <Country NAME="AbuDhabi" GMT="4" /> <Country NAME="Adelaide" GMT="9.5" /> <Country NAME="Alaska" GMT="-9" /> ... </Countries>
All data is hold in a class named Country:
private double _dGmt; private String _sName; private System.Drawing.Bitmap _imgFlag; public Country(String name, double diff) { Name = name; Gmt = diff; } public Country(String name, double diff, System.Drawing.Bitmap flag) { Name = name; Gmt = diff; _imgFlag = flag; } public System.Drawing.Bitmap ImgFlag { get { return _imgFlag; } set { _imgFlag = value; } } //the rest of the get/set properties follows here.
I provide two constructers, one for name and timezone and the second additionally with bitmap ’cause I maybe will someday add a country flag to each timezone.
After loading the form a typed list for Country objects is created.
I could have counted the lines of the xml and in depency to that created a typed array with a fix size but for about 50 elements it doesn’t really matter.
List<Country> lcountries = new List<Country>();
Now the xml file gets read into Country class:
private void ReadFromXml(List<Country> countries) { String name = String.Empty; double gmt = 0; String tmpGmt = String.Empty; String filename = @".\countries.xml"; if (!File.Exists(filename)) MessageBox.Show(filename + " can't be accessed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); else { XmlDocument doc = new XmlDocument(); doc.Load(); XmlElement root = doc.DocumentElement; foreach (XmlNode @daten in root.ChildNodes) { name = @daten.Attributes["NAME"].InnerText; tmpGmt = @daten.Attributes["GMT"].InnerText; tmpGmt = tmpGmt.Replace('.',','); Double.TryParse(tmpGmt, out gmt); countries.Add(new Country(name, gmt)); } } }
The most important thing, that saves a lot of lines, is the binding between combobox and List
this.cbCountries.DataSource = lcountries; this.cbCountries.DisplayMember = "Name"; this.cbCountries.DataBindings.Add("Text", lcountries, "Name");
The only think we have to do know is when the selected item of cbCountries is changed:
private void cbCountries_SelectedIndexChanged(object sender, EventArgs e) { Country selCountry = (Country)this.cbCountries.SelectedItem; _dDiff = selCountry.Gmt; }
Every second a timer (interval 1000ms) refreshes the label that shows the current date and time.
private void timer1_Tick(object sender, EventArgs e) { this.lblDate.Text = GetDate().ToShortDateString(); this.lblTime.Text = GetDate().ToLongTimeString(); } private DateTime GetDate() { DateTime t = DateTime.Now.ToUniversalTime(); t = t.AddHours(_dDiff); return t; }
Totally simple, written within 15 minutes and easy to comprend everybody else.
If you can also benefit from a worldclock application you can download it here.
It also works will with Linux using mono (>= 1.0). The only thing I had to take into account was the relative path of the xml file. There might be clearer solutions but to me this is the shortest way to archive my aim.
String filename = @".\countries.xml"; System.OperatingSystem osInfo = System.Environment.OSVersion; if (!osInfo.Platform.ToString().Contains("Win")) filename = @"./countries.xml";
For further information you can have a look at Nameing a File (Windows) on msdn.





