'From Squeak3.9 of 7 November 2006 [latest update: #7067] on 30 May 2009 at 9:29:09 am'! "Change Set: TimeZoneDatabase-GentooWorkaround-dtl Date: 30 May 2009 Author: David T. Lewis The zoneinfo files distributed with Gentoo apparently have additional binary data appended to each file. I do not know the reason for this, but if the trailing data is ignored we seem to get valid zoneinfo results. This change set disables the check in zoneinfo loader to ignore the trailing data. Note - need to understand the new format and see if it contains anything of real interest."! !TzFileLoader methodsFor: 'tzfile loading' stamp: 'dtl 5/30/2009 09:19'! load "Load from my fileStream, and answer an array of a TimeZoneRuleSet and a LeapSecondRuleSet. My name and fileStream instance variables should already be set. Close fileStream when the file load is complete." | ttisgmtcnt ttisstdcnt leapcnt timecnt typecnt charcnt transitionTimes ttinfoIndices ttinfoStructs abbreviations isStd isGmt rec timeZoneRuleSet leapSecondRuleSet | "Check magic ID for the file" ((self magic: fileStream) = 'TZif') ifFalse: [ self notify: 'bad magic for zoneinfo file'. fileStream close. ^ nil]. "Skip 16 unused characters" fileStream next: 16. "Read header information" ttisgmtcnt := self nextUnsignedIntFromNetworkOrderedBytes: fileStream. ttisstdcnt := self nextUnsignedIntFromNetworkOrderedBytes: fileStream. leapcnt := self nextUnsignedIntFromNetworkOrderedBytes: fileStream. timecnt := self nextUnsignedIntFromNetworkOrderedBytes: fileStream. typecnt := self nextUnsignedIntFromNetworkOrderedBytes: fileStream. charcnt := self nextUnsignedIntFromNetworkOrderedBytes: fileStream. "Read data for transition times" transitionTimes := OrderedCollection new. timecnt timesRepeat: [transitionTimes add: (self nextIntFromNetworkOrderedBytes: fileStream)]. ttinfoIndices := OrderedCollection new. timecnt timesRepeat: [ttinfoIndices add: (self nextUnsignedCharFrom: fileStream)]. "Read ttinfo data structures" ttinfoStructs := OrderedCollection new. typecnt timesRepeat: [ttinfoStructs add: (self ttinfoStructFrom: fileStream)]. "Read time zone name abbreviations" fileStream atEnd ifTrue: [self error: 'unexpected end of file']. abbreviations := fileStream next: charcnt. "Note: tzNames is redundant, as the same information will be saved in the transitionTimeTable. The names are stored separately here as a convenience for browsing time zones." tzNames := self getTzNameAbbreviationsFrom: abbreviations. "Read leap second information" leapSeconds := OrderedCollection new. leapcnt timesRepeat: [leapSeconds add: (self leapSecondStructFrom: fileStream)]. "Flags for standard/wall indicators, to indicate if transition times associated with local time types were specified as standard time or wall clock time, used when a time zone file is used in handling POSIX-style time zone environment variables." isStd := OrderedCollection new: typecnt. ttisstdcnt timesRepeat: [isStd add: (self nextBooleanCharFrom: fileStream)]. "Store the flags as element 4 of the corresponding ttinfoStruct" (1 to: ttisstdcnt) do: [:e | (ttinfoStructs at: e) at: 4 put: (isStd at: e)]. "Flags for UTC/local indicators, tell whether the transition times associated with local time types were specified as UTC or local time, used when a time zone file is used in handling POSIX-style time zone environment variables." isGmt := OrderedCollection new: typecnt. ttisgmtcnt timesRepeat: [isGmt add: (self nextBooleanCharFrom: fileStream)]. "Store the flags as element 5 of the corresponding ttinfoStruct" (1 to: ttisstdcnt) do: [:e | (ttinfoStructs at: e) at: 5 put: (isGmt at: e)]. "Relate the transition times to the ttinfoStruct data" transitionTable := Array new: timecnt. (1 to: timecnt) do: [:idx | rec := ttinfoStructs at: ((ttinfoIndices at: idx) + 1). transitionTable at: idx put: (TimeZoneRule new transitionTime: (transitionTimes at: idx); offsetSeconds: (rec at: 1); isDstFlag: (rec at: 2); abbreviation: (((ReadStream on: abbreviations) next: (rec at: 3); yourself) upTo: 0) asString asSymbol; isStdTimeTransition: (rec at: 4); isUtcTransition: (rec at: 5))]. "check commented out to test loading files from a Gentoo Linux distro -dtl fileStream atEnd ifFalse: [ self notify: 'zoneinfo parse error, should be at end of file'. fileStream close. ^ nil]." fileStream close. "Create an instance of LeapSecondRuleSet, or nil if no rules were found in this tzfile." (leapSeconds size = 0) ifTrue: [leapSecondRuleSet := nil] ifFalse: [leapSecondRuleSet := LeapSecondRuleSet new leapSecondTable: leapSeconds]. "Create an instance of TimeZoneRuleSet" timeZoneRuleSet := TimeZoneRuleSet new. timeZoneRuleSet timeZoneName: name. timeZoneRuleSet transitionTimeTable: transitionTable. timeZoneRuleSet leapSecondRuleSet: leapSecondRuleSet. timeZoneRuleSet tzNameAbbreviations: tzNames asArray. ^ Array with: timeZoneRuleSet with: leapSecondRuleSet! !