GemStone Server DateTime instances are stored as GMT (UTC) values,
and when they are replicated to the client, they are adjusted to
local time based on the local TimeZone settings on the client
Smalltalk. Under VA, The local TimeZone settings are calculated
based on Windows operating system information.
You must have the Windows operating system patches installed, for
correct information to come from the OS:
http://support.microsoft.com/kb/931836/
With the Windows patch applied, the data returned from the OS
exposes a bug in GBS. Given the new OS data, GBS does not
correctly calculate the start or end of DST. DateTimes in US and
Canadian time zones that are replicated from the server to GBS
during the week before DST begins according to the new rules, will
be incorrectly adjusted as if they were also in DST.
After installing the Windows OS patch, file in the methods below.
You must also execute
GbsTimeZone current: nil
to allow reinitialization from the OS information.
!GbsTimeZone class publicMethods !
approximateStartDateFrom: aDate
"given aDate which may be in a special form from MS, return a day from which
we can later compute the actual start of standard time or the actual dst time by
getting the previous day of the week (ie Sunday)"
^aDate wYear = 0
ifFalse:
[Date
newDay: aDate wDay
monthIndex: aDate wMonth
year: aDate wYear]
ifTrue:
["special format "
| fDate |
fDate := Date
newDay: 1
monthIndex: aDate wMonth
year: Date today year.
aDate wDay = 5
ifFalse: [fDate addDays: 6 + ((aDate wDay - 1) * 7)]
ifTrue: [fDate addDays: fDate daysLeftInMonth] "per bug 36391-GbsTimeZone instantiates incorrectly on VA"]!
clientDefaultInstance
"Return an instance of GbsTimeZone automatically initialized from the
operating system. If this isn't possible, return nil."
| tz dst std hasNoDst dstDate stdDate dstWeekDay stdWeekDay |
(self gbxResolve: #OSTimeZoneInformation) isNil ifTrue: [ ^nil ].
[
tz := (self gbxResolve: #OSTimeZoneInformation) new.
tz getTimeZoneInformation.
dst := tz DaylightDate.
std := tz StandardDate.
] whenExceptionDo: [ ^nil ].
hasNoDst := dst wDay = std wDay
and: [ dst wMonth = std wMonth
and: [ dst wYear = std wYear ]].
hasNoDst ifTrue:
[ ^ self
secondsFromGMT: tz Bias * -60
secondsForDST: 0
dayOfYearForDST: 0
dayOfWeekForDST: 0
secondsBeginDST: 0
dayOfYearForStandard: 0
dayOfWeekForStandard: 0
secondsBeginStandard: 0 ].
"From MSDN : sometimes the timeZone info has a special format for its dates. If wYear is 0,
wDayOfWeek represents the day (0-Sunday to 6-Saturday), and wDay represents the week of
the month (1 to 5 where 5 is always the last).
ex: wYear = 0, wWeekday = 0, wDay = 5, wMonth = 10 mean the last Sunday of October."
"Another problem is that for Win Sunday is 0 but it's 7 for others"
dstWeekDay := dst wDayOfWeek = 0
ifTrue: [7]
ifFalse: [dst wDayOfWeek].
stdWeekDay := std wDayOfWeek = 0
ifTrue: [7]
ifFalse: [std wDayOfWeek].
dstDate := self approximateStartDateFrom: dst.
stdDate := self approximateStartDateFrom: std.
^self
secondsFromGMT: tz Bias * -60
secondsForDST: tz DaylightBias * -60
dayOfYearForDST: dstDate dayOfYear - (Date leapYear: dstDate year)
dayOfWeekForDST: dstWeekDay
secondsBeginDST: (dst wHour * 60 * 60) + (dst wMinute * 60) + dst wSecond
dayOfYearForStandard: stdDate dayOfYear - (Date leapYear: stdDate year)
dayOfWeekForStandard: stdWeekDay
secondsBeginStandard: (std wHour * 60 * 60) + (std wMinute * 60) + std wSecond
! !
Last updated: 3/7/07