This article explains how to pick timezone from Windows registry and sort it for displaying purposes.
A time zone is a region of the earth that has the same standard time. All areas within that region will apply the same time. Because of the earth's spherical shape and the rotation of the earth, generally there are 24 regions with each region having a difference of 1 hour. But some occasions arise in some areas whereby it has a different time from that which its region should have.
When I designed my analog control, I decided to add timezone feature which made my control. A time zone dialog which works exactly like Windows time would be good enough. That's when I started to observe where Windows stores this information. After digging several sources, I found it stored in the registry, but then I realized that it would not be as easy as just reading the data. The process of making the timezone dialog is just as complex as creating the analog control itself.
While you set your time, you will see a time zone tab in the dialog. Alternatively, you can see Windows standard time zones in regional setting in control panel. In that dialog, you'll see a list of standard time zones. Our primary goal in this article is to retrieve the values and mimic its functionality.
Making the Code
The main object of this code is
TimeZones structure. The structure will have data from each timezone, including name and timespan. The processing will be done by
Our first preparation is to know where Windows stores this time zone list. It is stored in the registry, at "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\". In that key, there are many sub keys which provide information about each time zone. So, to retrieve the time zone list, we will look at these sub keys and read their values.
Design Basic Fundamentals
The first thing we should do is create a Time Zone structure that will contain time zone data. We don't need a class because it's only for displaying data and light processing. Besides, we will use a generic collection to store all time zone structures.
Private Structure TimeZones
Private _Display As String
Private _Name As String
Private _TimeSpan As TimeSpan
Public Property DisplayName() As String
Set(ByVal value As String)
_Display = value
Public Property Name() As String
Set(ByVal value As String)
_Name = value
Public ReadOnly Property Span() As TimeSpan
Next, we will analyze how time zone structures are in the registry where Windows stored them. As I told earlier, Windows stores time zone data in "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\". Each time zone data is stored on a sub key. In sub key, there are 4
string values, a dword values and a binary value. Basically, we need only one key which is a display value. The display key will be added in our time zone structures. From this display data, we will set time span for the time zone as well. To validate a time zone's time span, we will parse directly from display value. Display value will have data like this: "(GMT+07:00) Bangkok, Hanoi, Jakarta". In order to get time span, we will parse "(GMT+07:00)" in order to get 07:00 value. A new function will be needed to parse this information, so we add it in Time Zone structure.
Private Sub ValidateTimeSpan()
Select Case Mid(_Display, 5, 1)
Case ")" _TimeSpan = New TimeSpan(0, 0, 0)
_TimeSpan = New TimeSpan(CInt(Mid _
(_Display, 6, 2)), CInt(Mid(_Display, 9, 2)), 0)
_TimeSpan = New TimeSpan(CInt(Mid_
(_Display, 6, 2)) * -1, CInt(Mid(_Display, 9, 2)) * -1, 0)
Catch ex As Exception
_TimeSpan = New TimeSpan(0, 0, 0)
Now our base structure is ready to use. It's time to implement it in our class. For this sample, I'll use a form and a combo box for generating time zones.
Collect and Process Data for Display
What we have to do now is to initialize a collection variable that contains time zones. We will use
System.Collections.Generic.List for generating a list of
TimeZones. In the next step, we will fill the collection in our list from Windows registry. To access the registry, we will need
Private c As New System.Collections.Generic.List(Of TimeZones)
Private Sub GenerateTimezone()
Dim rk As RegistryKey = _
"SOFTWARE\" & _
"Microsoft\Windows NT\" & _
"CurrentVersion\Time Zones\", _
For Each sName As String In _
Dim tempKey As _
RegistryKey = _
Dim _tz As New TimeZones
_tz.DisplayName = _
_tz.Name = _
Now we have our list filled with Time Zones information. Unfortunately, the list is not ordered like it should be. Also, the time zone ordering is not done alphabetically. It is ordered by time span. Since standard collection class doesn't provide us with that kind of sorting, we have to make one by ourselves.
Private Function TimeZoneConvert(ByVal str As String) _
If Mid(str, 5, 1) = ")" Then
Return Mid(str, 5, 3) & Mid(str, 9, 2)
Private Function CompareTimezones(_
ByVal tz1 As TimeZones, _
ByVal tz2 As TimeZones) As Integer
If IsNothing(tz1) Then
If IsNothing(tz2) Then
If IsNothing(tz2) Then
Dim int1 As Integer = _
Dim int2 As Integer = _
If int1 > int2 Then
ElseIf int1 < int2 Then
Private Sub DisplayTimeZones()
For Each tz As TimeZones In c
If TimeZone.CurrentTimeZone.StandardName = _
cmbTimezone.Text = tz.DisplayName
The last one is to add a feature that will enable you to decide your own time. The modification code looks like the one described below:
Public ReadOnly Property NewSpan() As TimeSpan
If chkOwn.Checked = False Then
Return -TimeZone.CurrentTimeZone.GetUtcOffset(Now) + _
Dim ts As TimeSpan
If rAscend.Checked = True Then
ts = New TimeSpan(CInt(Mid(mtbValue.Text, 1, 2)), _
CInt(Mid(mtbValue.Text, 4, 2)), 0)
ElseIf rDecend.Checked = True Then
ts = New TimeSpan(CInt(Mid(mtbValue.Text, 1, 2)) * -1, _
CInt(Mid(mtbValue.Text, 4, 2)) * -1, 0)
Using the Code
TimeZoneForm should act as a dialog form. It will return the latest time after you setup your current time with the new
timezone settings. Doing so, the
TimeZoneForm will calculate and do the processing and return the expected value.
Points of Interest
There's something that's still on my mind, that is Daylight Saving Time. Since I do not live in a country with Daylight Saving Time, I stripped that feature because I still don't know exactly how it works. There's a subkey in each region that has DST settings and I don't have any idea of how to use it. If anyone could make some modifications or give me some information, I will gladly update my code.
- Version 1.0 - Initial release