AlHal2
asked on
More on Time zones in vb 2010
I'm using a Windows 7 machine. The code below is always exiting the function where it says "Exit do".
Is the subkey correct? If not, what should it be?
The program will run on a Windows 2012 R2 Standard machine. Again what should the subkey do?
Is the subkey correct? If not, what should it be?
The program will run on a Windows 2012 R2 Standard machine. Again what should the subkey do?
Dim hKey, curidx As Integer
Dim KeyName, KeyValue As String
Dim s As String
Dim lResult As Long
On Error GoTo EnumSubKeysErr
'SubKey = "Software\Microsoft\Windows NT\CurrentVersion\Time Zones"
SubKey = "SYSTEM\CurrentControlSet\Control\TimeZoneInformation"
' TopKey = "Computer\HKEY_LOCAL_MACHINE"
lResult = RegOpenKeyEx(TopKey, SubKey, 0, KEY_ALL_ACCESS, hKey)
MsgBox("lResult = " & lResult)
EnumSubKeys = hKey
MsgBox("hkey = " & hKey)
Do
KeyName = Space(MAX_SIZE)
KeyValue = Space(MAX_SIZE)
If RegEnumKey(hKey, curidx, KeyName, MAX_SIZE) <> ERROR_SUCCESS Then
Exit Do
End If
MsgBox("RegEnumKey = " & RegEnumKey(hKey, curidx, KeyName, MAX_SIZE))
ReDim Preserve LocTZI(curidx)
KeyName = StripNulls(KeyName)
LocTZI(curidx) = GetRegValueLTZI(SubKey & "\" & KeyName)
curidx = curidx + 1
Loop
RegCloseKey(hKey)
What are you trying to do with the code?
ASKER
For each city, I'm trying to find out the time and it's difference from UK time.
When you say "City", do you mean you have a list of cities, and you need to get their UTC offset?
Or are you trying to get the UTC offset for the machine where your code is running? If you're trying to do that you could use the BaseUTCOffset of a TimeZoneInfo variable:
Dim tzone As TimeZoneInfo = TimeZoneInfo.Local
Dim utc_offset As TimeSpan = tzone.BaseUTCOffset
utc_offset would contain the Offset values, and you could use the various methods of that variable as needed. For example, if you want to know the number of Hours of Offset:
Messagebox.Show(utc_offset .Hours)
https://msdn.microsoft.com/en-us/library/system.timezone.getutcoffset(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.timezoneinfo.baseutcoffset(v=vs.110).aspx
Or are you trying to get the UTC offset for the machine where your code is running? If you're trying to do that you could use the BaseUTCOffset of a TimeZoneInfo variable:
Dim tzone As TimeZoneInfo = TimeZoneInfo.Local
Dim utc_offset As TimeSpan = tzone.BaseUTCOffset
utc_offset would contain the Offset values, and you could use the various methods of that variable as needed. For example, if you want to know the number of Hours of Offset:
Messagebox.Show(utc_offset
https://msdn.microsoft.com/en-us/library/system.timezone.getutcoffset(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.timezoneinfo.baseutcoffset(v=vs.110).aspx
ASKER
I could be getting data from anywhere round the world and need to know the time in that place. Therefore I need a listing of timezones for everywhere.
So you would have a City + Country? Or some other type of data?
Unless you also receive the TimeZone of the "place", or something else you could translate to a TimeZone object, you'll need some way to determine where the UTC of that place would be. Will your data provide you with that?
Unless you also receive the TimeZone of the "place", or something else you could translate to a TimeZone object, you'll need some way to determine where the UTC of that place would be. Will your data provide you with that?
ASKER
The data will have a city name which I can cross reference with the time zone object.
ASKER
I'm trying to replicate what happens in this vb6 code. Does that clarify what I am trying to do?
Public Function GetTZICollection(sRegKey As String) As Boolean
GetTZICollection = EnumSubKeys(HKLM, sRegKey)
End Function
Private Function EnumSubKeys(TopKey As Long, SubKey As String, Optional colTZ As Collection) As Boolean
Dim hKey As Long, curidx As Long, KeyName As String, KeyValue As String
Dim s As String
RegOpenKeyEx TopKey, SubKey, 0&, KEY_ALL_ACCESS, hKey
EnumSubKeys = hKey
Do
KeyName = Space$(MAX_SIZE)
KeyValue = Space$(MAX_SIZE)
If RegEnumKey(hKey, curidx, KeyName, MAX_SIZE) <> ERROR_SUCCESS Then Exit Do
ReDim Preserve LocTZI(curidx)
KeyName = StripNulls(KeyName)
LocTZI(curidx) = GetRegValueLTZI(SubKey & "\" & KeyName)
curidx = curidx + 1
Loop
RegCloseKey hKey
End Function
Private Function GetRegValueLTZI(sKey As String) As LOCALE_TIME_ZONE_INFORMATION
Dim hKey As Long, ltzi As LOCALE_TIME_ZONE_INFORMATION, sTemp As String
If RegOpenKeyEx(HKLM, sKey, 0&, KEY_ALL_ACCESS, hKey) <> ERROR_SUCCESS Then Exit Function
Dim lResult As Long
lResult = RegQueryValueEx(hKey, "TZI", 0&, REG_BINARY, ltzi, 44&)
sTemp = Space$(MAX_SIZE)
Call RegQueryValueEx(hKey, "Display", 0&, REG_SZ, ByVal sTemp, MAX_SIZE)
ltzi.DisplayName = StripNulls(sTemp)
sTemp = Space$(MAX_SIZE)
Call RegQueryValueEx(hKey, "Std", 0&, REG_SZ, ByVal sTemp, MAX_SIZE)
ltzi.StandardName = StripNulls(sTemp)
sTemp = Space$(MAX_SIZE)
Call RegQueryValueEx(hKey, "Dlt", 0&, REG_SZ, ByVal sTemp, MAX_SIZE)
ltzi.DaylightName = StripNulls(sTemp)
sTemp = Space$(MAX_SIZE)
Call RegQueryValueEx(hKey, "MapID", 0&, REG_SZ, ByVal sTemp, MAX_SIZE)
ltzi.MapID = StripNulls(sTemp)
RegCloseKey hKey
GetRegValueLTZI = ltzi
End Function
Public Function GetRegValueStr(sKey As String, sSubKey As String) As String
Dim hKey As Long, sTemp As String
GetRegValueStr = ""
Dim agc As Integer
agc = RegOpenKeyEx(HKLM, sKey, 0&, KEY_ALL_ACCESS, hKey)
If agc <> ERROR_SUCCESS Then
Exit Function
End If
sTemp = Space$(MAX_SIZE)
If RegQueryValueEx(hKey, sSubKey, 0&, REG_SZ, ByVal sTemp, MAX_SIZE) = ERROR_SUCCESS Then
GetRegValueStr = Trim$(StripNulls(sTemp))
End If
RegCloseKey hKey
End Function
Private Function StripNulls(ByVal sText As String) As String
Dim nPosition&
StripNulls = sText
nPosition = InStr(sText, vbNullChar)
If nPosition Then StripNulls = Left$(sText, nPosition - 1)
If Len(sText) Then If Left$(sText, 1) = vbNullChar Then StripNulls = ""
End Function
Public Function UTCToLocalDate(dt As Date, tz As LOCALE_TIME_ZONE_INFORMATION) As Date
Dim d As Date
Log.WriteLine ("in UTCToLocaldate")
Log.WriteLine ("dt in is " & dt)
Log.WriteLine ("tz.bias info is " & tz.Bias)
Log.WriteLine ("tz.standardbias info is " & tz.StandardBias)
Log.WriteLine ("tz.daylightbias info is " & tz.DaylightBias)
' Log.WriteLine ("tz.standarddate info is " & tz.StandardDate)
' Log.WriteLine ("tz.daylightdate info is " & tz.DaylightDate)
Log.WriteLine ("tz.displayname info is " & tz.DisplayName)
Log.WriteLine ("tz.standardname info is " & tz.StandardName)
Log.WriteLine ("tz.daylightname info is " & tz.DaylightName)
Log.WriteLine ("tz.mapid info is " & tz.MapID)
Log.WriteLine "In UTCToLocalDate"
d = DateSerial(Year(dt), Month(dt), Day(dt)) + TimeSerial(Hour(dt), Minute(dt) - tz.Bias - tz.DaylightBias, Second(dt))
Log.WriteLine "d is " & d
If Not IsDayLight(d, tz) Then
Log.WriteLine "It is not IsDayLight"
d = DateSerial(Year(dt), Month(dt), Day(dt)) + TimeSerial(Hour(dt), Minute(dt) - tz.Bias, Second(dt))
End If
UTCToLocalDate = d
Log.WriteLine "leaving UTCToLocalDate"
End Function
Public Function LocalDateToUTC(dt As Date, tz As LOCALE_TIME_ZONE_INFORMATION) As Date
Log.WriteLine ("in LocaldateToUTC")
Log.WriteLine ("dt in is " & dt)
Log.WriteLine ("tz.bias info is " & tz.Bias)
Log.WriteLine ("tz.standardbias info is " & tz.StandardBias)
Log.WriteLine ("tz.daylightbias info is " & tz.DaylightBias)
' Log.WriteLine ("tz.standarddate info is " & tz.StandardDate)
' Log.WriteLine ("tz.daylightdate info is " & tz.DaylightDate)
Log.WriteLine ("tz.displayname info is " & tz.DisplayName)
Log.WriteLine ("tz.standardname info is " & tz.StandardName)
Log.WriteLine ("tz.daylightname info is " & tz.DaylightName)
Log.WriteLine ("tz.mapid info is " & tz.MapID)
If IsDayLight(dt, tz) Then
Log.WriteLine "IsDaylight is true"
LocalDateToUTC = DateSerial(Year(dt), Month(dt), Day(dt)) + TimeSerial(Hour(dt), Minute(dt) + tz.Bias + tz.DaylightBias, Second(dt))
Else
Log.WriteLine "IsDaylight is false"
LocalDateToUTC = DateSerial(Year(dt), Month(dt), Day(dt)) + TimeSerial(Hour(dt), Minute(dt) + tz.Bias, Second(dt))
End If
End Function
Private Function IsDayLight(dt As Date, tz As LOCALE_TIME_ZONE_INFORMATION) As Boolean
Dim dlBegin As Date, dlEnd As Date, date_in As Date
Log.WriteLine (" ")
Log.WriteLine ("In function IsDaylight")
Log.WriteLine ("dt in is " & dt)
date_in = Format(dt, IsDaylight_format)
With tz.DaylightDate
If .wYear Then
dlBegin = DateSerial(Year(dt), .wMonth, .wDay)
Else
dlBegin = WeekDayToDate(Year(dt), .wMonth, .wDayOfWeek, .wDay)
End If
dlBegin = dlBegin + TimeSerial(.wHour, .wMinute, .wSecond)
End With
With tz.StandardDate
If .wYear Then
dlEnd = DateSerial(Year(dt), .wMonth, .wDay)
Else
dlEnd = WeekDayToDate(Year(dt), .wMonth, .wDayOfWeek, .wDay)
End If
dlEnd = dlEnd + TimeSerial(.wHour, .wMinute, .wSecond)
End With
Log.WriteLine ("dlbegin is " & dlBegin)
Log.WriteLine ("dlend is " & dlEnd)
Log.WriteLine ("date_in is " & date_in)
' sometimes dlbegin doesn't have a valid date in it.
' check by looking for "/" symbol.
If InStr(dlBegin, "/") = 0 Or InStr(dlEnd, "/") = 0 Then
Log.WriteLine ("invalid date encountered - assuming not daylight")
Else
If dlBegin < dlEnd Then
Log.WriteLine ("not australia")
If date_in > dlBegin And date_in < dlEnd Then IsDayLight = True
Else
Log.WriteLine ("australia")
'Australia!!!
If date_in < dlEnd Or date_in > dlBegin Then IsDayLight = True
End If
End If
End Function
Public Function WeekDayToDate(y As Integer, m As Integer, wDay As Integer, nDay As Integer) As Date
Dim d As Date, n As Integer, s As String, count As Integer, i As Integer
For i = 1 To 31
d = DateSerial(y, m, i)
If Month(d) > m Then Exit For
If wDay = Weekday(d) - 1 Then
count = count + 1
WeekDayToDate = d
If count = nDay Then Exit For
End If
Next i
End Function
Public Function IsNT() As Boolean
Dim verinfo As OSVERSIONINFO
verinfo.dwOSVersionInfoSize = Len(verinfo)
If (GetVersionEx(verinfo)) = 0 Then Exit Function
If verinfo.dwPlatformId = 2 Then IsNT = True
End Function
The two methods I cited earlier do much the same thing in .NET. From what I can gather, that code reads the registry on the machine, and then performs calculations based on those setting. The trouble is that code in .NET retrieves data from the machine where it's run, and then determines the UTC offset.
You won't be able to do that, if all you have is a CITY name. There are many, many Cities with the same name in different regions. For example, in the US, every state has a city named "Springfield", so if all you have is that name, you could not possibly know the time zone for that specific city.
Even if you know more information about that area (the City and State, for US-based addresses) you still cannot know the UTC offset based solely on that. You'd have to keep a table of all cities and such, and then determine the UTC offset from there. There are web services that might provide you what you're after, assuming you have sufficient data to provide the web service.
But you wouldn't search the registry of the local machine to determine UTC offset based on the name of a City.
You won't be able to do that, if all you have is a CITY name. There are many, many Cities with the same name in different regions. For example, in the US, every state has a city named "Springfield", so if all you have is that name, you could not possibly know the time zone for that specific city.
Even if you know more information about that area (the City and State, for US-based addresses) you still cannot know the UTC offset based solely on that. You'd have to keep a table of all cities and such, and then determine the UTC offset from there. There are web services that might provide you what you're after, assuming you have sufficient data to provide the web service.
But you wouldn't search the registry of the local machine to determine UTC offset based on the name of a City.
ASKER
My mistake. We have the names of exchanges / bourses rather than cities.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Suppose I'm given the name of a timezone in a config file. how can I find out how many hours different it is to UK time?
For example the difference between Central European Standard Time will depend on whether the UK is using GMT or BST and whether the other people have their clocks forward or backward.
Also how can I convert this to vb.net
For example the difference between Central European Standard Time will depend on whether the UK is using GMT or BST and whether the other people have their clocks forward or backward.
Also how can I convert this to vb.net
Public Function IsNT() As Boolean
Dim verinfo As OSVERSIONINFO
verinfo.dwOSVersionInfoSize = Len(verinfo)
If (GetVersionEx(verinfo)) = 0 Then Exit Function
If verinfo.dwPlatformId = 2 Then IsNT = True
End Function
ASKER
Thanks.