[squeak-dev] Time zone help

David T. Lewis lewis at mail.msen.com
Sat May 30 13:41:11 UTC 2009


On Fri, May 29, 2009 at 12:01:41PM -0400, C. David Shaffer wrote:
> David T. Lewis wrote:
> >
> > Use TimeZoneDatabase. No plugin is required.
> >   http://wiki.squeak.org/squeak/1076
> >
> > Latest source is always here:
> >   http://wiki.squeak.org/squeak/1076
> >
> >   
> Thanks Dave.  I loaded the released version 1-2-5-dtl under Gentoo Linux
> I end up in an endless stream of warnings "should be at end of stream"
> during parsing of the time zone files.  Example stack trace attached.
> Disabling the warning dialog gets me through to another warning "nil is
> not a valid abbreviation for a time zone".  Stack trace attached. 
> Proceeding through that the load completes but I don't think my time
> zones loaded properly:
> 
>   TimeZoneDatabase grepFor: 'Detroit'   ---> #()
> 
> I also tried New_York.  I verified that these files are in my
> /usr/share/zoneinfo directory.  I seem to recall going through this
> process before.  Is there a patch?

Hi David,

For reasons that I do not understand, the New_York zoneinfo file from
your Gentoo distribution is larger than I expected, and contains additional
binary data following the time zone table data. My file loader checks
for this, and throws up the warning that you are seeing. I don't know
if this is some Gentoo-specific thing, or if there is some alternate
file format that I am not aware of.

In any case, ignoring the additional data in the Gentoo zoneinfo files
appears to have no ill effects. I have attached a patch that disables
my syntax check, and that hopefully will enable you to load the zoneinfo
files on your Gentoo system when you evaluate "TimeZoneDatabase initialize".

Please let me know if this works for you.

Dave

-------------- next part --------------
'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! !



More information about the Squeak-dev mailing list