Programming Time and TimeZone

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi everybody,
What is difference between a local time and a system time, Correct if I am
wrong, system time is time of the system server where your computer is
connected. So, if I would change system time I need to change the tme on the
server. Right?
How would you set(change the local time programatically? Also, using
DateTime.UtcNow is to get system time? How to change the system time
programatically? How to get and set(change) Time Zone? The System is a
Satellite(GPRS). Is that possible to change the time there?

The situation is this, if the application is to be used by say user from
another country, they have their own local time and Time Zone Info, and their
own system (server) time. I like these to be configurable. I know that to
change timezone I need a class and method inside the System.Globalization.
Can you help narrow it down or pinpoint it for setting and getting time zone?
Also, how to get a list of Time Zone to be displayed in a Combo Box? Is there
a method for this?

C# or VB.Net will be ok.

denpsia
 
*Update*
If the system is a remote server say in different country. How to change and
view this time?

Getting local time from any country where application is running:
DateTime.UtcNow

den2005
 
I try to find these same functions (CE) in XP.

[DllImport("coredll.dll", SetLastError=true)]
public static extern int SetLocalTime (ref SystemTime lpSystemTime);

[DllImport("coredll.dll", SetLastError=true)]
public static extern bool SetSystemTime (ref SystemTime lpSystemTime);

[DllImport("coredll.dll", SetLastError=true)]
public static extern bool SetTimeZoneInformation (ref TimeZoneInformation
lpTimeZoneInformation);

[DllImport("coredll.dll", SetLastError=true)]
public static extern void GetTimeZoneInformation(ref TimeZoneInformation
lpTimeZoneInformation);

[DllImport("coredll.dll", EntryPoint="GetSystemTime", SetLastError=true)]
public static extern void GetSystemTime(ref SystemTime lpSystemTime);


I used this api function SetSystemTime() of Kernel32.dll and it does not
change time in my

computer. Anybody knows how to fixed this?

Code:
private void SetLocalTime(DateTime dtNew)
{
int dw = -1;
SYSTEMTIME st = new SYSTEMTIME();
st.wDay = dtNew.Day;

if (dtNew.DayOfWeek == DayOfWeek.Sunday )
dw = 0;
else if (dtNew.DayOfWeek == DayOfWeek.Monday)
dw = 1;
else if (dtNew.DayOfWeek == DayOfWeek.Tuesday )
dw = 2;
else if (dtNew.DayOfWeek == DayOfWeek.Wednesday )
dw = 3;
else if (dtNew.DayOfWeek == DayOfWeek.Thursday )
dw = 4;
else if (dtNew.DayOfWeek == DayOfWeek.Friday )
dw = 5;
else if (dtNew.DayOfWeek == DayOfWeek.Saturday )
dw = 6;

st.wDayOfWeek = dw;
st.wHour = dtNew.Hour;
st.wMinute = dtNew.Minute;
st.wSecond = dtNew.Second;
st.wMonth = dtNew.Month;
st.wYear = dtNew.Year;

uint uRes = SetSystemTime(ref st); \\ returns 0

if (uRes <= 0)
MessageBox.Show("Unable to change Local time.");
}

den2005
 
I wrote this class two years ago that should solve your problem.

Please let me know if it contains any bug :)

regards.-

mau

Imports Microsoft.Win32
Imports System.Runtime.InteropServices
Imports System.Globalization
Friend Class CustomTimeZone
Inherits System.TimeZone
' system types
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure SYSTEMTIME
Dim wYear As Short
Dim wMonth As Short
Dim wDayOfWeek As Short
Dim wDay As Short
Dim wHour As Short
Dim wMinute As Short
Dim wSecond As Short
Dim wMilliseconds As Short
End Structure
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure TZI
Dim Bias As Integer
Dim StandardBias As Integer
Dim DaylightBias As Integer
Dim StandardDate As SYSTEMTIME
Dim DaylightDate As SYSTEMTIME
End Structure
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure
TIME_ZONE_INFORMATION
Dim Bias As Integer
<VBFixedString(32)> Dim StandardName As String
Dim StandardDate As SYSTEMTIME
Dim StandardBias As Integer
<VBFixedString(32)> Dim DaylightName As String
Dim DaylightDate As SYSTEMTIME
Dim DaylightBias As Integer
End Structure
' system timezones
Private Shared Zones As TimeZonesCollection
' private vars
Dim _displayName As String
Dim _id As Integer
Dim _timeZoneInfo As TIME_ZONE_INFORMATION
Private Shared _currentZone As CustomTimeZone
Private Sub New(ByVal fromTZI As TZI, ByVal zoneName As String, ByVal
zoneDisplay As String, _
ByVal zoneID As Integer, ByVal zoneDaylightName As String)
_displayName = zoneDisplay
_id = zoneID
_timeZoneInfo.Bias = fromTZI.Bias
_timeZoneInfo.StandardName = zoneName
_timeZoneInfo.StandardDate = fromTZI.StandardDate
_timeZoneInfo.StandardBias = fromTZI.StandardBias
_timeZoneInfo.DaylightName = zoneDaylightName
_timeZoneInfo.DaylightDate = fromTZI.DaylightDate
_timeZoneInfo.DaylightBias = fromTZI.DaylightBias
End Sub
#Region "Private methods"
Private Shared Function CheckWindowsNT() As Boolean
' ritorna true se è windows NT o 2000 o XP
If Environment.OSVersion.Platform = PlatformID.Win32NT Then Return True
End Function
Private Shared Function SystemTimeToDateTime(ByVal S As SYSTEMTIME, ByVal
Year As Integer) As Date
If S.wYear <> 0 Then
' data assoluta
Return New Date(S.wYear, S.wMonth, S.wDay, S.wHour, S.wMinute, S.wSecond,
S.wMilliseconds)
Else
' data relativa, es. ultima domenica di marzo
Dim DT As Date
Dim Diff As Integer
If S.wDay <= 4 Then
Dim FirstMonthDayOfWeek As Integer
DT = New Date(Year, S.wMonth, 1, S.wHour, S.wMinute, S.wSecond,
S.wMilliseconds)
FirstMonthDayOfWeek = DT.DayOfWeek
Diff = S.wDayOfWeek - FirstMonthDayOfWeek
If Diff < 0 Then Diff += 7
Diff = 7 * S.wDay - 1
If Diff > 0 Then DT = DT.AddDays(Diff)
Else
Dim C As New GregorianCalendar
Dim LastDayDayOfWeek As Integer
DT = New Date(Year, S.wMonth, C.GetDaysInMonth(Year, S.wMonth), S.wHour,
S.wMinute, S.wSecond, S.wMilliseconds)
LastDayDayOfWeek = DT.DayOfWeek
Diff = LastDayDayOfWeek - S.wDayOfWeek
If Diff < 0 Then Diff += 7
If Diff > 0 Then DT = DT.AddDays(-Diff)
End If
Return DT
End If
End Function
Private Shared Function CalculateUTCOffset(ByVal time As Date, ByVal
daylightTimes As DaylightTime) As TimeSpan
Dim D1, D2 As Date
Dim T As TimeSpan
If daylightTimes Is Nothing Then Return TimeSpan.Zero
T = daylightTimes.Delta
If T.Ticks > 0 Then
D1 = daylightTimes.Start.AddTicks(daylightTimes.Delta.Ticks)
D2 = daylightTimes.End
Else
D1 = daylightTimes.Start
D2 = daylightTimes.End.AddTicks(-daylightTimes.Delta.Ticks)
End If
If D1 > D2 Then
If Not (time < D2) And Not (time >= D1) Then Return TimeSpan.Zero
Return daylightTimes.Delta
End If
If time > D1 And time < D2 Then Return daylightTimes.Delta
Return TimeSpan.Zero
End Function
#End Region
#Region "Public Properties"
Public Overrides ReadOnly Property DaylightName() As String
Get
If _timeZoneInfo.StandardDate.wMonth = 0 Then Return
_timeZoneInfo.StandardName
Return _timeZoneInfo.DaylightName
End Get
End Property
Public Overrides ReadOnly Property StandardName() As String
Get
Return _timeZoneInfo.StandardName
End Get
End Property
Public Overridable ReadOnly Property DisplayName() As String
Get
Return _displayName
End Get
End Property
Public ReadOnly Property ID() As Integer
Get
Return _id
End Get
End Property
#End Region
#Region "Public Shared Members"
Public Shared ReadOnly Property GMT() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(85)
End Get
End Property
Public Shared ReadOnly Property PST() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(4)
End Get
End Property
Public Shared ReadOnly Property EST() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(35)
End Get
End Property
Public Shared Function EnumTimeZones() As TimeZonesCollection
' Registry Constants
Const SKEY_NT = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones"
Const SKEY_9X = "SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
If Zones Is Nothing Then
Dim SubKey As String
Dim regKey, regTimeKey As RegistryKey
Dim I As Integer
Dim SubKeys As String()
Dim objtzi As TZI
Dim Bytes() As Byte
SyncLock GetType(CustomTimeZone)
If Zones Is Nothing Then ' previene una race-condition
If CheckWindowsNT() Then SubKey = SKEY_NT Else SubKey = SKEY_9X
regKey = Registry.LocalMachine.OpenSubKey(SubKey)
Try
SubKeys = regKey.GetSubKeyNames
Dim tziType As Type = GetType(TZI)
Dim tziSize As Integer = Marshal.SizeOf(tziType)
Dim sZoneName, sZoneDisplay, sDaylightName As String
Dim Index As Integer
Zones = New TimeZonesCollection
For I = 0 To SubKeys.Length - 1
regTimeKey = regKey.OpenSubKey(SubKeys(I))
Bytes = regTimeKey.GetValue("TZI")
sZoneName = regTimeKey.GetValue("Std")
sZoneDisplay = regTimeKey.GetValue("Display")
sDaylightName = regTimeKey.GetValue("Dlt")
Index = regTimeKey.GetValue("Index")
regTimeKey.Close()
If Not (Bytes Is Nothing OrElse Bytes.Length <> tziSize) Then
Dim handle As GCHandle
Dim Buffer As IntPtr
handle = GCHandle.Alloc(Bytes, GCHandleType.Pinned)
Buffer = handle.AddrOfPinnedObject
objtzi = CType(Marshal.PtrToStructure(Buffer, tziType), TZI)
handle.Free()
Zones.Add(New CustomTimeZone(objtzi, sZoneName, sZoneDisplay, Index,
sDaylightName))
End If
Next
regTimeKey = Nothing
Finally
regKey.Close()
If Not (regTimeKey Is Nothing) Then regTimeKey.Close()
End Try
End If
End SyncLock
End If
Return Zones
End Function
Public Shared Function ConvertDateTime(ByVal localDate As Date, ByVal
sourceZone As TimeZone, ByVal targetZone As TimeZone) As Date
Dim utcDate As Date
utcDate = sourceZone.ToUniversalTime(localDate)
Return targetZone.ToLocalTime(utcDate)
End Function
Public Shared Shadows Function CurrentTimeZone() As CustomTimeZone
If _currentZone Is Nothing Then
Dim I As Integer
Dim currentZone As TimeZone
SyncLock GetType(CustomTimeZone)
If _currentZone Is Nothing Then
currentZone = TimeZone.CurrentTimeZone
For I = 0 To EnumTimeZones.Count
If Zones.Item(I).StandardName = currentZone.StandardName Then
_currentZone = Zones(I)
Exit For
End If
Next
End If
End SyncLock
End If
Return _currentZone
End Function
#End Region
#Region "Public Methods"
Public Overrides Function GetHashCode() As Integer
Return _id
End Function
Public Overrides Function ToString() As String
Return StandardName
End Function
Public Overrides Function GetDaylightChanges(ByVal year As Integer) As
System.Globalization.DaylightTime
Dim daylightTime As DaylightTime
If year < 1 OrElse year > 9999 Then Throw New
ArgumentOutOfRangeException("Year must be beetween 1 and 9999!")
If _timeZoneInfo.StandardDate.wMonth = 0 Then
' l'ora legale non è usata
Return New DaylightTime(Date.MinValue, Date.MinValue, TimeSpan.Zero)
Else
Dim startDaylight, endDaylight As Date
Dim DurataOra As TimeSpan
' calcola l'inizio e la fine dell'ora legale
startDaylight = SystemTimeToDateTime(_timeZoneInfo.DaylightDate, year)
endDaylight = SystemTimeToDateTime(_timeZoneInfo.StandardDate, year)
DurataOra = New TimeSpan(-_timeZoneInfo.DaylightBias *
TimeSpan.TicksPerMinute)
Return New DaylightTime(startDaylight, endDaylight, DurataOra)
End If
End Function
Public Overrides Function GetUtcOffset(ByVal time As Date) As
System.TimeSpan
Dim T As TimeSpan
T = CalculateUTCOffset(time, GetDaylightChanges(time.Year))
Return New TimeSpan(T.Ticks - _timeZoneInfo.Bias * TimeSpan.TicksPerMinute)
End Function
#End Region
End Class
Friend Class TimeZonesCollection
Implements ICollection
Dim _Zones As SortedList
Friend Sub New()
_Zones = New SortedList(80)
End Sub
Friend Sub Add(ByVal zone As CustomTimeZone)
_Zones.Add(zone.ID, zone)
End Sub
#Region "Public Properties"
Public ReadOnly Property Count() As Integer Implements
System.Collections.ICollection.Count
Get
Return _Zones.Count
End Get
End Property
Public ReadOnly Property IsSynchronized() As Boolean Implements
System.Collections.ICollection.IsSynchronized
Get
Return (_Zones.IsSynchronized)
End Get
End Property
Public ReadOnly Property SyncRoot() As Object Implements
System.Collections.ICollection.SyncRoot
Get
SyncLock GetType(TimeZonesCollection)
Return Me
End SyncLock
End Get
End Property
Default Public ReadOnly Property Item(ByVal index As Integer) As
CustomTimeZone
Get
Return CType(_Zones.GetByIndex(index), CustomTimeZone)
End Get
End Property
#End Region
#Region "Public Methods"
Public Sub CopyTo(ByVal array As System.Array, ByVal index As Integer)
Implements System.Collections.ICollection.CopyTo
_Zones.CopyTo(array, index)
End Sub
Public Function GetEnumerator() As System.Collections.IEnumerator Implements
System.Collections.IEnumerable.GetEnumerator
Return _Zones.GetEnumerator
End Function
Public Function FindZoneID(ByVal id As Integer) As CustomTimeZone
Return _Zones.Item(id)
End Function
#End Region
End Class
 
Thanks mauro, I need some time to be able to reply, I need to convert your
vb.net to C# codes. Unless you a C# version. I never yet handle ant TimeZone
and Property with implements.


denpsia
 
mauro,
I unable to convert some of your vb.net codes to C#, I am compiling and
still errors.
I try to re-construct if possible to make it work in C#.

Anybody,
How to change this using "implements" keyboard in C#? I change the ocde
below to next code and still error.

Code:
Public ReadOnly Property Count() As Integer Implements
System.Collections.ICollection.Count
Get
Return _Zones.Count
End Get
End Property

Public Function GetEnumerator() As System.Collections.IEnumerator Implements
System.Collections.IEnumerable.GetEnumerator
Return _Zones.GetEnumerator
End Function

C# code:
Code:
public readonly int Count() : System.Collections.ICollection.Count()
{
get
{
return _Zones.Count;
}
}

Error Results:
1st Property:
.. . .\form1.cs(457,32): error CS1002: ; expected
.. . .\form1.cs(457,70): error CS1519: Invalid token '(' in class, struct, or
interface member

declaration

2nd Property:
....\form1.cs(500,11): error CS1518: Expected class, delegate, enum,
interface, or struct


I should just remove the "shadows" keywords here. No effect on its primary
functionality?

Code:
Public Shared Shadows Function CurrentTimeZone() As CustomTimeZone
If _currentZone Is Nothing Then
Dim I As Integer
Dim currentZone As TimeZone

SyncLock GetType(CustomTimeZone)

If _currentZone Is Nothing Then
currentZone = TimeZone.CurrentTimeZone
For I = 0 To EnumTimeZones.Count
If Zones.Item(I).StandardName = currentZone.StandardName Then
_currentZone = Zones(I)
Exit For
End If
Next
End If
End SyncLock
End If
Return _currentZone
End Function

How about Default in C#? What is the meaning by "by using indexers"?

Code:
Default Public ReadOnly Property Item(ByVal index As Integer) As
CustomTimeZone
Get
Return CType(_Zones.GetByIndex(index), CustomTimeZone)
End Get
End Property
 
Why don't you just put this code in a separate dll project? So you can
compile it and link it with to your c# project...

mau.

den 2005 said:
mauro,
I unable to convert some of your vb.net codes to C#, I am compiling and
still errors.
I try to re-construct if possible to make it work in C#.

Anybody,
How to change this using "implements" keyboard in C#? I change the ocde
below to next code and still error.

Code:
Public ReadOnly Property Count() As Integer Implements
System.Collections.ICollection.Count
Get
Return _Zones.Count
End Get
End Property

Public Function GetEnumerator() As System.Collections.IEnumerator
Implements
System.Collections.IEnumerable.GetEnumerator
Return _Zones.GetEnumerator
End Function

C# code:
Code:
public readonly int Count() : System.Collections.ICollection.Count()
{
get
{
return _Zones.Count;
}
}

Error Results:
1st Property:
. . .\form1.cs(457,32): error CS1002: ; expected
. . .\form1.cs(457,70): error CS1519: Invalid token '(' in class, struct,
or
interface member

declaration

2nd Property:
...\form1.cs(500,11): error CS1518: Expected class, delegate, enum,
interface, or struct


I should just remove the "shadows" keywords here. No effect on its primary
functionality?

Code:
Public Shared Shadows Function CurrentTimeZone() As CustomTimeZone
If _currentZone Is Nothing Then
Dim I As Integer
Dim currentZone As TimeZone

SyncLock GetType(CustomTimeZone)

If _currentZone Is Nothing Then
currentZone = TimeZone.CurrentTimeZone
For I = 0 To EnumTimeZones.Count
If Zones.Item(I).StandardName = currentZone.StandardName Then
_currentZone = Zones(I)
Exit For
End If
Next
End If
End SyncLock
End If
Return _currentZone
End Function

How about Default in C#? What is the meaning by "by using indexers"?

Code:
Default Public ReadOnly Property Item(ByVal index As Integer) As
CustomTimeZone
Get
Return CType(_Zones.GetByIndex(index), CustomTimeZone)
End Get
End Property
--
MCP Year 2005, Philippines


den 2005 said:
Thanks mauro, I need some time to be able to reply, I need to convert
your
vb.net to C# codes. Unless you a C# version. I never yet handle ant
TimeZone
and Property with implements.


denpsia
 
Thanks for reply mauro, that would put additional overhead and affect
performance. The application will be installed in a wireless device. So,
I need to manage the resources carefully. Is there a way to say limit the
codes
just like using an api function? Thanks again.

Den2005
--
MCP Year 2005, Philippines


mauro said:
Why don't you just put this code in a separate dll project? So you can
compile it and link it with to your c# project...

mau.

den 2005 said:
mauro,
I unable to convert some of your vb.net codes to C#, I am compiling and
still errors.
I try to re-construct if possible to make it work in C#.

Anybody,
How to change this using "implements" keyboard in C#? I change the ocde
below to next code and still error.

Code:
Public ReadOnly Property Count() As Integer Implements
System.Collections.ICollection.Count
Get
Return _Zones.Count
End Get
End Property

Public Function GetEnumerator() As System.Collections.IEnumerator
Implements
System.Collections.IEnumerable.GetEnumerator
Return _Zones.GetEnumerator
End Function

C# code:
Code:
public readonly int Count() : System.Collections.ICollection.Count()
{
get
{
return _Zones.Count;
}
}

Error Results:
1st Property:
. . .\form1.cs(457,32): error CS1002: ; expected
. . .\form1.cs(457,70): error CS1519: Invalid token '(' in class, struct,
or
interface member

declaration

2nd Property:
...\form1.cs(500,11): error CS1518: Expected class, delegate, enum,
interface, or struct


I should just remove the "shadows" keywords here. No effect on its primary
functionality?

Code:
Public Shared Shadows Function CurrentTimeZone() As CustomTimeZone
If _currentZone Is Nothing Then
Dim I As Integer
Dim currentZone As TimeZone

SyncLock GetType(CustomTimeZone)

If _currentZone Is Nothing Then
currentZone = TimeZone.CurrentTimeZone
For I = 0 To EnumTimeZones.Count
If Zones.Item(I).StandardName = currentZone.StandardName Then
_currentZone = Zones(I)
Exit For
End If
Next
End If
End SyncLock
End If
Return _currentZone
End Function

How about Default in C#? What is the meaning by "by using indexers"?

Code:
Default Public ReadOnly Property Item(ByVal index As Integer) As
CustomTimeZone
Get
Return CType(_Zones.GetByIndex(index), CustomTimeZone)
End Get
End Property
--
MCP Year 2005, Philippines


den 2005 said:
Thanks mauro, I need some time to be able to reply, I need to convert
your
vb.net to C# codes. Unless you a C# version. I never yet handle ant
TimeZone
and Property with implements.


denpsia
--
MCP Year 2005, Philippines


:

I wrote this class two years ago that should solve your problem.

Please let me know if it contains any bug :)

regards.-

mau

Imports Microsoft.Win32
Imports System.Runtime.InteropServices
Imports System.Globalization
Friend Class CustomTimeZone
Inherits System.TimeZone
' system types
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure
SYSTEMTIME
Dim wYear As Short
Dim wMonth As Short
Dim wDayOfWeek As Short
Dim wDay As Short
Dim wHour As Short
Dim wMinute As Short
Dim wSecond As Short
Dim wMilliseconds As Short
End Structure
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure TZI
Dim Bias As Integer
Dim StandardBias As Integer
Dim DaylightBias As Integer
Dim StandardDate As SYSTEMTIME
Dim DaylightDate As SYSTEMTIME
End Structure
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure
TIME_ZONE_INFORMATION
Dim Bias As Integer
<VBFixedString(32)> Dim StandardName As String
Dim StandardDate As SYSTEMTIME
Dim StandardBias As Integer
<VBFixedString(32)> Dim DaylightName As String
Dim DaylightDate As SYSTEMTIME
Dim DaylightBias As Integer
End Structure
' system timezones
Private Shared Zones As TimeZonesCollection
' private vars
Dim _displayName As String
Dim _id As Integer
Dim _timeZoneInfo As TIME_ZONE_INFORMATION
Private Shared _currentZone As CustomTimeZone
Private Sub New(ByVal fromTZI As TZI, ByVal zoneName As String, ByVal
zoneDisplay As String, _
ByVal zoneID As Integer, ByVal zoneDaylightName As String)
_displayName = zoneDisplay
_id = zoneID
_timeZoneInfo.Bias = fromTZI.Bias
_timeZoneInfo.StandardName = zoneName
_timeZoneInfo.StandardDate = fromTZI.StandardDate
_timeZoneInfo.StandardBias = fromTZI.StandardBias
_timeZoneInfo.DaylightName = zoneDaylightName
_timeZoneInfo.DaylightDate = fromTZI.DaylightDate
_timeZoneInfo.DaylightBias = fromTZI.DaylightBias
End Sub
#Region "Private methods"
Private Shared Function CheckWindowsNT() As Boolean
' ritorna true se è windows NT o 2000 o XP
If Environment.OSVersion.Platform = PlatformID.Win32NT Then Return True
End Function
Private Shared Function SystemTimeToDateTime(ByVal S As SYSTEMTIME,
ByVal
Year As Integer) As Date
If S.wYear <> 0 Then
' data assoluta
Return New Date(S.wYear, S.wMonth, S.wDay, S.wHour, S.wMinute,
S.wSecond,
S.wMilliseconds)
Else
' data relativa, es. ultima domenica di marzo
Dim DT As Date
Dim Diff As Integer
If S.wDay <= 4 Then
Dim FirstMonthDayOfWeek As Integer
DT = New Date(Year, S.wMonth, 1, S.wHour, S.wMinute, S.wSecond,
S.wMilliseconds)
FirstMonthDayOfWeek = DT.DayOfWeek
Diff = S.wDayOfWeek - FirstMonthDayOfWeek
If Diff < 0 Then Diff += 7
Diff = 7 * S.wDay - 1
If Diff > 0 Then DT = DT.AddDays(Diff)
Else
Dim C As New GregorianCalendar
Dim LastDayDayOfWeek As Integer
DT = New Date(Year, S.wMonth, C.GetDaysInMonth(Year, S.wMonth),
S.wHour,
S.wMinute, S.wSecond, S.wMilliseconds)
LastDayDayOfWeek = DT.DayOfWeek
Diff = LastDayDayOfWeek - S.wDayOfWeek
If Diff < 0 Then Diff += 7
If Diff > 0 Then DT = DT.AddDays(-Diff)
End If
Return DT
End If
End Function
Private Shared Function CalculateUTCOffset(ByVal time As Date, ByVal
daylightTimes As DaylightTime) As TimeSpan
Dim D1, D2 As Date
Dim T As TimeSpan
If daylightTimes Is Nothing Then Return TimeSpan.Zero
T = daylightTimes.Delta
If T.Ticks > 0 Then
D1 = daylightTimes.Start.AddTicks(daylightTimes.Delta.Ticks)
D2 = daylightTimes.End
Else
D1 = daylightTimes.Start
D2 = daylightTimes.End.AddTicks(-daylightTimes.Delta.Ticks)
End If
If D1 > D2 Then
If Not (time < D2) And Not (time >= D1) Then Return TimeSpan.Zero
Return daylightTimes.Delta
End If
If time > D1 And time < D2 Then Return daylightTimes.Delta
Return TimeSpan.Zero
End Function
#End Region
#Region "Public Properties"
Public Overrides ReadOnly Property DaylightName() As String
Get
If _timeZoneInfo.StandardDate.wMonth = 0 Then Return
_timeZoneInfo.StandardName
Return _timeZoneInfo.DaylightName
End Get
End Property
Public Overrides ReadOnly Property StandardName() As String
Get
Return _timeZoneInfo.StandardName
End Get
End Property
Public Overridable ReadOnly Property DisplayName() As String
Get
Return _displayName
End Get
End Property
Public ReadOnly Property ID() As Integer
Get
Return _id
End Get
End Property
#End Region
#Region "Public Shared Members"
Public Shared ReadOnly Property GMT() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(85)
End Get
End Property
Public Shared ReadOnly Property PST() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(4)
End Get
End Property
Public Shared ReadOnly Property EST() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(35)
End Get
End Property
Public Shared Function EnumTimeZones() As TimeZonesCollection
' Registry Constants
Const SKEY_NT = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time
Zones"
Const SKEY_9X = "SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
If Zones Is Nothing Then
Dim SubKey As String
Dim regKey, regTimeKey As RegistryKey
Dim I As Integer
Dim SubKeys As String()
Dim objtzi As TZI
Dim Bytes() As Byte
SyncLock GetType(CustomTimeZone)
If Zones Is Nothing Then ' previene una race-condition
If CheckWindowsNT() Then SubKey = SKEY_NT Else SubKey = SKEY_9X
regKey = Registry.LocalMachine.OpenSubKey(SubKey)
Try
SubKeys = regKey.GetSubKeyNames
Dim tziType As Type = GetType(TZI)
Dim tziSize As Integer = Marshal.SizeOf(tziType)
Dim sZoneName, sZoneDisplay, sDaylightName As String
Dim Index As Integer
Zones = New TimeZonesCollection
For I = 0 To SubKeys.Length - 1
 
Hi mauro,
I tried to follow your advice of compiling your code so I put them in a
class library

project(VB/.Net) and coompile them. These are errors resulted. I tried to
add MustInherit like

this:
Friend MustInherit Class CustomTimeZone

Error Messages:

...\TimeZone\Class1.vb(236): 'CurrentTimeZone' is not a member of
'TimeZone.TimeZone'.

...\TimeZone\Class1.vb(207): 'New' cannot be used on class
'TimeZone.CustomTimeZone' because it contains a 'MustOverride' member that
has not been overridden.

...\TimeZone\Class1.vb(260): 'Public Overrides Function
GetDaylightChanges(year As Integer) As System.Globalization.DaylightTime()'
cannot override 'Public Overridable MustOverride Function
GetDaylightChanges(year As Integer) As System.Globalization.DaylightTime'
because they differ by their return types.

...\TimeZone\Class1.vb(238): 'StandardName' is not a member of
'TimeZone.TimeZone'.

...\TimeZone\Class1.vb(225): 'ToLocalTime' is not a member of
'TimeZone.TimeZone'.

...\TimeZone\Class1.vb(224): 'ToUniversalTime' is not a member of
'TimeZone.TimeZone'.

...\TimeZone\Class1.vb(11): Class 'CustomTimeZone' must either be declared
'MustInherit' or override the following inherited 'MustOverride' member(s):
Public Overridable MustOverride Function GetDaylightChanges(year As Integer)
As System.Globalization.DaylightTime.

...\TimeZone\Class1.vb(279): Value of type '1-dimensional array of
System.Globalization.DaylightTime' cannot be converted to
'System.Globalization.DaylightTime'.

...\TimeZone\Class1.vb(273): Value of type
'System.Globalization.DaylightTime' cannot be converted to '1-dimensional
array of System.Globalization.DaylightTime'.

...\TimeZone\Class1.vb(265): Value of type
'System.Globalization.DaylightTime' cannot be converted to '1-dimensional
array of System.Globalization.DaylightTime'.


I would try to resolve them.


den2005
--
MCP Year 2005, Philippines


den 2005 said:
Thanks for reply mauro, that would put additional overhead and affect
performance. The application will be installed in a wireless device. So,
I need to manage the resources carefully. Is there a way to say limit the
codes
just like using an api function? Thanks again.

Den2005
--
MCP Year 2005, Philippines


mauro said:
Why don't you just put this code in a separate dll project? So you can
compile it and link it with to your c# project...

mau.

den 2005 said:
mauro,
I unable to convert some of your vb.net codes to C#, I am compiling and
still errors.
I try to re-construct if possible to make it work in C#.

Anybody,
How to change this using "implements" keyboard in C#? I change the ocde
below to next code and still error.

Code:
Public ReadOnly Property Count() As Integer Implements
System.Collections.ICollection.Count
Get
Return _Zones.Count
End Get
End Property

Public Function GetEnumerator() As System.Collections.IEnumerator
Implements
System.Collections.IEnumerable.GetEnumerator
Return _Zones.GetEnumerator
End Function

C# code:
Code:
public readonly int Count() : System.Collections.ICollection.Count()
{
get
{
return _Zones.Count;
}
}

Error Results:
1st Property:
. . .\form1.cs(457,32): error CS1002: ; expected
. . .\form1.cs(457,70): error CS1519: Invalid token '(' in class, struct,
or
interface member

declaration

2nd Property:
...\form1.cs(500,11): error CS1518: Expected class, delegate, enum,
interface, or struct


I should just remove the "shadows" keywords here. No effect on its primary
functionality?

Code:
Public Shared Shadows Function CurrentTimeZone() As CustomTimeZone
If _currentZone Is Nothing Then
Dim I As Integer
Dim currentZone As TimeZone

SyncLock GetType(CustomTimeZone)

If _currentZone Is Nothing Then
currentZone = TimeZone.CurrentTimeZone
For I = 0 To EnumTimeZones.Count
If Zones.Item(I).StandardName = currentZone.StandardName Then
_currentZone = Zones(I)
Exit For
End If
Next
End If
End SyncLock
End If
Return _currentZone
End Function

How about Default in C#? What is the meaning by "by using indexers"?

Code:
Default Public ReadOnly Property Item(ByVal index As Integer) As
CustomTimeZone
Get
Return CType(_Zones.GetByIndex(index), CustomTimeZone)
End Get
End Property
--
MCP Year 2005, Philippines


:

Thanks mauro, I need some time to be able to reply, I need to convert
your
vb.net to C# codes. Unless you a C# version. I never yet handle ant
TimeZone
and Property with implements.


denpsia
--
MCP Year 2005, Philippines


:

I wrote this class two years ago that should solve your problem.

Please let me know if it contains any bug :)

regards.-

mau

Imports Microsoft.Win32
Imports System.Runtime.InteropServices
Imports System.Globalization
Friend Class CustomTimeZone
Inherits System.TimeZone
' system types
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure
SYSTEMTIME
Dim wYear As Short
Dim wMonth As Short
Dim wDayOfWeek As Short
Dim wDay As Short
Dim wHour As Short
Dim wMinute As Short
Dim wSecond As Short
Dim wMilliseconds As Short
End Structure
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure TZI
Dim Bias As Integer
Dim StandardBias As Integer
Dim DaylightBias As Integer
Dim StandardDate As SYSTEMTIME
Dim DaylightDate As SYSTEMTIME
End Structure
<StructLayout(LayoutKind.Sequential, pack:=2)> Private Structure
TIME_ZONE_INFORMATION
Dim Bias As Integer
<VBFixedString(32)> Dim StandardName As String
Dim StandardDate As SYSTEMTIME
Dim StandardBias As Integer
<VBFixedString(32)> Dim DaylightName As String
Dim DaylightDate As SYSTEMTIME
Dim DaylightBias As Integer
End Structure
' system timezones
Private Shared Zones As TimeZonesCollection
' private vars
Dim _displayName As String
Dim _id As Integer
Dim _timeZoneInfo As TIME_ZONE_INFORMATION
Private Shared _currentZone As CustomTimeZone
Private Sub New(ByVal fromTZI As TZI, ByVal zoneName As String, ByVal
zoneDisplay As String, _
ByVal zoneID As Integer, ByVal zoneDaylightName As String)
_displayName = zoneDisplay
_id = zoneID
_timeZoneInfo.Bias = fromTZI.Bias
_timeZoneInfo.StandardName = zoneName
_timeZoneInfo.StandardDate = fromTZI.StandardDate
_timeZoneInfo.StandardBias = fromTZI.StandardBias
_timeZoneInfo.DaylightName = zoneDaylightName
_timeZoneInfo.DaylightDate = fromTZI.DaylightDate
_timeZoneInfo.DaylightBias = fromTZI.DaylightBias
End Sub
#Region "Private methods"
Private Shared Function CheckWindowsNT() As Boolean
' ritorna true se è windows NT o 2000 o XP
If Environment.OSVersion.Platform = PlatformID.Win32NT Then Return True
End Function
Private Shared Function SystemTimeToDateTime(ByVal S As SYSTEMTIME,
ByVal
Year As Integer) As Date
If S.wYear <> 0 Then
' data assoluta
Return New Date(S.wYear, S.wMonth, S.wDay, S.wHour, S.wMinute,
S.wSecond,
S.wMilliseconds)
Else
' data relativa, es. ultima domenica di marzo
Dim DT As Date
Dim Diff As Integer
If S.wDay <= 4 Then
Dim FirstMonthDayOfWeek As Integer
DT = New Date(Year, S.wMonth, 1, S.wHour, S.wMinute, S.wSecond,
S.wMilliseconds)
FirstMonthDayOfWeek = DT.DayOfWeek
Diff = S.wDayOfWeek - FirstMonthDayOfWeek
If Diff < 0 Then Diff += 7
Diff = 7 * S.wDay - 1
If Diff > 0 Then DT = DT.AddDays(Diff)
Else
Dim C As New GregorianCalendar
Dim LastDayDayOfWeek As Integer
DT = New Date(Year, S.wMonth, C.GetDaysInMonth(Year, S.wMonth),
S.wHour,
S.wMinute, S.wSecond, S.wMilliseconds)
LastDayDayOfWeek = DT.DayOfWeek
Diff = LastDayDayOfWeek - S.wDayOfWeek
If Diff < 0 Then Diff += 7
If Diff > 0 Then DT = DT.AddDays(-Diff)
End If
Return DT
End If
End Function
Private Shared Function CalculateUTCOffset(ByVal time As Date, ByVal
daylightTimes As DaylightTime) As TimeSpan
Dim D1, D2 As Date
Dim T As TimeSpan
If daylightTimes Is Nothing Then Return TimeSpan.Zero
T = daylightTimes.Delta
If T.Ticks > 0 Then
D1 = daylightTimes.Start.AddTicks(daylightTimes.Delta.Ticks)
D2 = daylightTimes.End
Else
D1 = daylightTimes.Start
D2 = daylightTimes.End.AddTicks(-daylightTimes.Delta.Ticks)
End If
If D1 > D2 Then
If Not (time < D2) And Not (time >= D1) Then Return TimeSpan.Zero
Return daylightTimes.Delta
End If
If time > D1 And time < D2 Then Return daylightTimes.Delta
Return TimeSpan.Zero
End Function
#End Region
#Region "Public Properties"
Public Overrides ReadOnly Property DaylightName() As String
Get
If _timeZoneInfo.StandardDate.wMonth = 0 Then Return
_timeZoneInfo.StandardName
Return _timeZoneInfo.DaylightName
End Get
End Property
Public Overrides ReadOnly Property StandardName() As String
Get
Return _timeZoneInfo.StandardName
End Get
End Property
Public Overridable ReadOnly Property DisplayName() As String
Get
Return _displayName
End Get
End Property
Public ReadOnly Property ID() As Integer
Get
Return _id
End Get
End Property
#End Region
#Region "Public Shared Members"
Public Shared ReadOnly Property GMT() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(85)
End Get
End Property
Public Shared ReadOnly Property PST() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(4)
End Get
End Property
Public Shared ReadOnly Property EST() As CustomTimeZone
Get
Return EnumTimeZones.FindZoneID(35)
End Get
End Property
Public Shared Function EnumTimeZones() As TimeZonesCollection
' Registry Constants
Const SKEY_NT = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time
Zones"
Const SKEY_9X = "SOFTWARE\Microsoft\Windows\CurrentVersion\Time Zones"
If Zones Is Nothing Then
Dim SubKey As String
Dim regKey, regTimeKey As RegistryKey
Dim I As Integer
Dim SubKeys As String()
Dim objtzi As TZI
 
Back
Top