You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
7.1 KiB
203 lines
7.1 KiB
15 years ago
|
|
||
|
|
||
|
VZIC README
|
||
|
===========
|
||
|
|
||
|
This is 'vzic', a program to convert the Olson timezone database files into
|
||
|
VTIMEZONE files compatible with the iCalendar specification (RFC2445).
|
||
|
|
||
|
(The name is based on the 'zic' program which converts the Olson files into
|
||
|
time zone information files used by several Unix C libraries, including
|
||
|
glibc. See zic(8) and tzfile(5).)
|
||
|
|
||
|
|
||
|
|
||
|
REQUIREMENTS
|
||
|
============
|
||
|
|
||
|
You need the Olson timezone database files, which can be found at:
|
||
|
|
||
|
ftp://elsie.nci.nih.gov/pub/
|
||
|
|
||
|
(Old versions can be found at ftp://munnari.oz.au/pub/oldtz/)
|
||
|
|
||
|
|
||
|
Vzic also uses the GLib library (for hash tables, dynamic arrays, and date
|
||
|
calculations). You need version 2.0 or higher. You can get this from:
|
||
|
|
||
|
http://www.gtk.org
|
||
|
|
||
|
|
||
|
|
||
|
BUILDING
|
||
|
========
|
||
|
|
||
|
Edit the Makefile to set the OLSON_DIR, PRODUCT_ID and TZID_PREFIX variables.
|
||
|
|
||
|
Then run 'make'.
|
||
|
|
||
|
|
||
|
|
||
|
RUNNING
|
||
|
=======
|
||
|
|
||
|
Run 'vzic'.
|
||
|
|
||
|
The output is placed in the zoneinfo subdirectory by default,
|
||
|
but you can use the --output-dir options to set another toplevel output
|
||
|
directory.
|
||
|
|
||
|
By default it outputs VTIMEZONEs that try to be compatible with Outlook
|
||
|
(2000, at least). Outlook can't handle certain iCalendar constructs in
|
||
|
VTIMEZONEs, such as RRULEs using BYMONTHDAY, so it has to adjust the RRULEs
|
||
|
slightly to get Outlook to parse them. Unfortunately this means they are
|
||
|
slightly wrong. If given the --pure option, vzic outputs the exact data,
|
||
|
without worrying about compatability.
|
||
|
|
||
|
NOTE: We don't convert all the Olson files. We skip 'backward', 'etcetera',
|
||
|
'leapseconds', 'pacificnew', 'solar87', 'solar88' and 'solar89', 'factory'
|
||
|
and 'systemv', since these don't really provide any useful timezones.
|
||
|
See vzic.c.
|
||
|
|
||
|
|
||
|
|
||
|
MERGING CHANGES INTO A MASTER SET OF VTIMEZONES
|
||
|
===============================================
|
||
|
|
||
|
The Olson timezone files are updated fairly often, so we need to build new
|
||
|
sets of VTIMEZONE files. Though we have to be careful to ensure that the TZID
|
||
|
of updated timezones is also updated, since it must remain unique.
|
||
|
|
||
|
We use a version number on the end of the TZID prefix (see the TZIDPrefix
|
||
|
variable in vzic-output.c) to ensure this uniqueness.
|
||
|
|
||
|
But we don't want to update the version numbers of VTIMEZONEs which have not
|
||
|
changed. So we use the vzic-merge.pl Perl script. This merges in the new set
|
||
|
of VTIMEZONEs with a 'master' set. It compares each new VTIMEZONE file with
|
||
|
the one in the master set (ignoring changes to the TZID). If the new
|
||
|
VTIMEZONE file is different, it copies it to the master set and sets the
|
||
|
version number to the old VTIMEZONE's version number + 1.
|
||
|
|
||
|
To use vzic-merge.pl you must change the $MASTER_ZONEINFO_DIR and
|
||
|
$NEW_ZONEINFO_DIR variables at the top of the file to point to your 2 sets of
|
||
|
VTIMEZONEs. You then just run the script. (I recommend you keep a backup of
|
||
|
the old master VTIMEZONE files, and use diff to compare the new master set
|
||
|
with the old one, in case anything goes wrong.)
|
||
|
|
||
|
You must merge in changes to the zones.tab file by hand.
|
||
|
|
||
|
Note that some timezones are renamed or removed occasionally, so applications
|
||
|
should be able to cope with this.
|
||
|
|
||
|
|
||
|
|
||
|
COMPATABILITY NOTES
|
||
|
===================
|
||
|
|
||
|
It seems that Microsoft Outlook is very picky about the iCalendar files it
|
||
|
will accept. (I've been testing with Outlook 2000. I hope the other versions
|
||
|
are no worse.) Here's a few problems we've had with the VTIMEZONEs:
|
||
|
|
||
|
o Outlook doesn't like any years before 1600. We were using '1st Jan 0001'
|
||
|
in all VTIMEZONEs to specify the first UTC offset known for the timezone.
|
||
|
(The Olson data does not give a start date for this.)
|
||
|
|
||
|
Now we just skip this first component for most timezones. The UTC offset
|
||
|
can still be found from the TZOFFSETFROM property of the first component.
|
||
|
|
||
|
Though some timezones only specify one UTC offset that applies forever,
|
||
|
so in these cases we output '1st Jan 1970' (Indian/Cocos,
|
||
|
Pacific/Johnston).
|
||
|
|
||
|
o Outlook doesn't like the BYMONTHDAY specifier in RRULEs.
|
||
|
|
||
|
We have changed most of the VTIMEZONEs to use things like 'BYDAY=2SU'
|
||
|
rather than 'BYMONTHDAY=8,9,10,11,12,13,14;BYDAY=SU', though some of
|
||
|
them were impossible to convert correctly so they are not always correct.
|
||
|
|
||
|
o Outlook doesn't like TZOFFSETFROM/TZOFFSETTO properties which include a
|
||
|
seconds component, e.g. 'TZOFFSETFROM:+110628'.
|
||
|
Quite a lot of the Olson timezones include seconds in their UTC offsets,
|
||
|
though no timezones currently have a UTC offset that uses the seconds
|
||
|
value.
|
||
|
|
||
|
We've rounded all UTC offsets to the nearest minute. Since all timezone
|
||
|
offsets currently used have '00' as the seconds offset, this doesn't lose
|
||
|
us much.
|
||
|
|
||
|
o Outlook doesn't like lines being split in certain places, even though
|
||
|
the iCalendar spec says they can be split anywhere.
|
||
|
|
||
|
o Outlook can only handle one RDATE or a pair of RRULEs. So we had to remove
|
||
|
all historical data.
|
||
|
|
||
|
|
||
|
TESTING
|
||
|
=======
|
||
|
|
||
|
Do a 'make test-vic', then run ./test-vic.
|
||
|
|
||
|
The test-vzic program compares our libical code and VTIMEZONE data against
|
||
|
the Unix functions like mktime(). It steps over a period of time (1970-2037)
|
||
|
converting from UTC to a given timezone and back again every 15 minutes.
|
||
|
Any differences are output into the test-output directory.
|
||
|
|
||
|
The output matches for all of the timezones, except in a few places where the
|
||
|
result can't be determined. So I think we can be fairly confident that the
|
||
|
VTIMEZONEs are correct.
|
||
|
|
||
|
Note that you must use the same Olson data in libical that the OS is using
|
||
|
for mktime() etc. For example, I am using RedHat 9 which uses tzdata2002d,
|
||
|
so I converted this to VTIMEZONE files and installed it into the libical
|
||
|
timezone data directory before testing. (You need to use '--pure' when
|
||
|
creating the VTIMEZONE files as well.)
|
||
|
|
||
|
|
||
|
Testing the Parsing Code
|
||
|
------------------------
|
||
|
|
||
|
Run 'make test-parse'.
|
||
|
|
||
|
This runs 'vzic --dump' and 'perl-dump' and compares the output. The diff
|
||
|
commands should not produce any output.
|
||
|
|
||
|
'vzic --dump' dumps all the parsed data out in the original Olson format,
|
||
|
but without comments. The files are written into the ZonesVzic and RulesVzic
|
||
|
subdirectories of the zoneinfo directory.
|
||
|
|
||
|
'make perl-dump' runs the vzic-dump.pl perl script which outputs the files
|
||
|
in the same format as 'vzic --dump' in the ZonesPerl and RulesPerl
|
||
|
subdirectories. The perl script doesn't actually parse the fields; it only
|
||
|
strips comments and massages the fields so we have the same output format.
|
||
|
|
||
|
Currently they both produce exactly the same output so we know the parsing
|
||
|
code is OK.
|
||
|
|
||
|
|
||
|
Testing the VTIMEZONE Files
|
||
|
---------------------------
|
||
|
|
||
|
Run 'make test-changes'.
|
||
|
|
||
|
This runs 'vzic --dump-changes' and 'test-vzic --dump-changes' and compares
|
||
|
the output. The diff command should not produce any output.
|
||
|
|
||
|
Both commands output timezone changes for each zone up to a specific year
|
||
|
(2030) into files for each timezone. It outputs the timezone changes in a
|
||
|
list in this format:
|
||
|
|
||
|
Timezone Name Date and Time of Change in UTC New Offset from UTC
|
||
|
|
||
|
America/Dawson 26 Oct 1986 2:00:00 -0800
|
||
|
|
||
|
Unfortunately there are some differences here, but they all happen before
|
||
|
1970 so it doesn't matter too much. It looks like the libical code has
|
||
|
problems determining things like 'last Sunday of the month' before 1970.
|
||
|
This is because it uses mktime() etc. which can't really handle dates
|
||
|
before 1970.
|
||
|
|
||
|
|
||
|
|
||
|
Damon Chaplin <damon@gnome.org>, 25 Oct 2003.
|
||
|
|