
Signature
Cordially,
Chip Pearson
Pearson Software Consulting, LLC
www.cpearson.com
(email address is on the web site)
<cut>
> This clearly doesn't work The help isn't very clear, but it was my
> understanding that if I set the values of TZI.DaylightDate to the
> value as shown above, GetTimeZoneInformation would populate the
> TZI.DaylightDate and TZI.StandardDate with the dates of the start of
> Daylight and Standard times.
Calling the API function returns values similar to what you have set, it
doesn't return the specific dates. You'd need to translate the "day d of
week w of month m" into a date for the specific year you are interested in.
Keep in mind that as of 2007 the values are changing and after you're system
is updated with the new start & end points then calculations based on that
for previous years are going to be wrong.

Signature
Reply to the group so all can participate
VB.Net: "Fool me once..."
I had to do this recently, and found a few interesting twists in the plot.
Firstly, the date/times at which standard/daylight-saving times begin are
not real ones, they're encoded ones. You cannot just call DateSerial using
their fields. Let me know if you want the conversion algorithm. The old docs
are woefully inadequate, but I did find some updated ones. Plus I found some
supposed VB samples on the Internet which were totally wrong and obviously
untested.
The second issue - which I never resolved - was how is it possible to
convert, say, a time of 1am on a day when the clocks go back at 2am. There
are effectively two instances of 1am that day: standard and daylight-saving,
and it's not possible for an API to know which you've given it (without an
extra parameter).
I had to write a function that does what you're trying, but for an arbitrary
timezone that may not be the current one. I did consider converting the
specified local time to UTC twice - once with the daylight-saving data
turned off - and test whether the two results were different. However, I
elected, in the end, to do pretty much what you're doing, i.e. just test
against the date/times at which the changeover occurs.
Tony Proctor
> I need to write a function that will return True or False indicating whether
> a specified date is in the Daylight Savings Time period for that year. The
[quoted text clipped - 34 lines]
> Private Const TIME_ZONE_ID_DAYLIGHT = 2
> Private Const TIME_ZONE_ID_INVALID = -1
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
> Public Function IsDateInDST(DateVal As Long) As Boolean
>
[quoted text clipped - 22 lines]
>
> End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
> This clearly doesn't work The help isn't very clear, but it was my
> understanding that if I set the values of TZI.DaylightDate to the value as
[quoted text clipped - 22 lines]
>
> Thank you for ANY advice.
Tony Proctor - 27 Dec 2006 14:58 GMT
These might be useful to yourself Chip, or anyone else reading this thread
later. They're extracted from a bigger timezone class I have here.
tTimeZoneInfo is a local TIME_ZONE_INFORMATION variable representing the
selected timezone.
'=====================
Private Function dLoadChangePoint(tDateTime As SYSTEMTIME) As Date
' Loads a daylight-saving changeover date/time (as encoded in
TIME_ZONE_INFORMATION) into a VB Date/time
Dim dTemp As Date
Dim dFirstWeekday As Long 'Weekday of 1st day in month (Sun=0,
Sat=6)
With tDateTime
If .wMonth = 0 Then
oLocale.Error lErrNoDaylightSaving, TypeName(Me)
Else
If .wYear > 0 Then
dTemp = DateSerial(.wYear, .wMonth, .wDay)
Else
Select Case .wDay
Case 1 To 4: 'Week 1 to week 4
' Calculate the first day in the month, and then
calculate the appropriate day
' that the time zone change will occur at
dFirstWeekday = Weekday(DateSerial(Year(Date), .wMonth,
1), vbSunday) - 1
dTemp = DateSerial(Year(Date), .wMonth, _
((.wDayOfWeek - dFirstWeekday) + (.wDay - 1) * 7) +
1)
Case 5: 'Last week in month
' Calculate the month's last day, then work back to the
appropriate weekday
dTemp = DateSerial(Year(Date), .wMonth + 1, 0)
dTemp = DateAdd("d", (.wDayOfWeek - (Weekday(dTemp,
vbSunday) - 1) - 7) Mod 7, dTemp)
End Select
End If
End If
dLoadChangePoint = dTemp + TimeSerial(.wHour, .wMinute, .wSecond)
End With
End Function
Public Property Get DaylightStart() As Date
' Returns the date/time at which the transition from standard time to
daylight-saving
' time occurs, or the VB base date (30/12/1899) if no daylight-saving
defined
If tTimeZoneInfo.DaylightDate.wMonth <> 0 Then
DaylightStart = dLoadChangePoint(tTimeZoneInfo.DaylightDate)
End If
End Property
Public Property Get StandardStart() As Date
' Returns the date/time at which the transition from daylight-saving time to
standard
' time occurs, or the VB base date (30/12/1899) if no daylight-saving
defined
If tTimeZoneInfo.StandardDate.wMonth <> 0 Then
StandardStart = dLoadChangePoint(tTimeZoneInfo.StandardDate)
End If
End Property
Public Function InDayLightSaving(dDateTime As Date) As Boolean
' Determines whether a local time is in "daylight saving" mode or not
If tTimeZoneInfo.DaylightDate.wMonth <> 0 Then
InDayLightSaving = (dDateTime >=
dLoadChangePoint(tTimeZoneInfo.DaylightDate) And _
dDateTime < dLoadChangePoint(tTimeZoneInfo.StandardDate))
End If
End Function
'=================
The following notes are from some updated MSDN docs, and explain how the
changeover times are encoded...
"To select the correct day in the month, set the wYear member to zero, the
wHour and wMinute members to the transition time, the wDayOfWeek member to
the appropriate weekday, and the wDay member to indicate the occurrence of
the day of the week within the month (1 to 5, where 5 indicates the final
occurrence during the month if that day of the week does not occur 5 times).
Using this notation, specify the 2:00a.m. on the first Sunday in April as
follows: wHour = 2, wMonth = 4, wDayOfWeek = 0, wDay = 1. Specify 2:00a.m.
on the last Thursday in October as follows: wHour = 2, wMonth = 10,
wDayOfWeek = 4, wDay = 5."
Tony Proctor
> I had to do this recently, and found a few interesting twists in the plot.
>
[quoted text clipped - 60 lines]
> > Private Const TIME_ZONE_ID_DAYLIGHT = 2
> > Private Const TIME_ZONE_ID_INVALID = -1
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
> '
> > Public Function IsDateInDST(DateVal As Long) As Boolean
[quoted text clipped - 23 lines]
> >
> > End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
> '
> >
[quoted text clipped - 27 lines]
> >
> > Thank you for ANY advice.