Giter VIP home page Giter VIP logo

vzic's Introduction

VZIC README

This is vzic, a program to convert the IANA (formerly Olson) timezone database files into VTIMEZONE files compatible with the iCalendar specification (RFC2445).

(The name is based on the zic program which converts the IANA files into time zone information files used by several Unix C libraries, including glibc. See zic(8) and tzfile(5).)

The vzic software is licensed according to the terms of the GNU General Public License version 2.0 or later (see LICENSES/GPL-2.0-or-later.txt). The IANA timezone database files are in the public domain.

REQUIREMENTS

You need the IANA (formerly known as Olson) timezone database files (tzdata), which can be found at:

http://www.iana.org/time-zones

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

PREPARATIONS

gunzip and untar the tzdata file:

  % mkdir tzdata2014g
  % cd  tzdata2014g; tar xvfz ../tzdata2014g.tar.gz; cd ..

BUILDING

Edit the Makefile to set the OLSON_DIR (in this case to tzdata2014g), PRODUCT_ID and TZID_PREFIX variables.

Then run make -B.

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 compatibility.

NOTE: We don't convert all the IANA 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 IANA 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 add the new timezones in the zones.tab file by hand. diff the new zones.tab versus the current zones.tab

Note that some timezones are renamed or removed occasionally, so applications should be able to cope with this.

COMPATIBILITY 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 IANA 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 IANA 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-vzic, then run ./test-vzic.

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 IANA 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 [email protected], 25 Oct 2003.

vzic's People

Contributors

benfortuna avatar brong avatar dilyanpalauzov avatar drlue avatar fboudra avatar krop avatar ksmurchison avatar minichma avatar pre-commit-ci[bot] avatar rsto avatar tadzik avatar winterz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

vzic's Issues

Issue with Cairo Timezone

The actual timezone for Cairo is UTC +2 reference : https://www.timeanddate.com/time/zone/egypt/cairo
and for 2020 — 2029 | No changes, UTC +2 hours all of the period, but zoneinfo Cairo.ics shows +3
even though TZOFFSETTO:+0200 why the result returned is +3

N:Africa/Cairo
X-PROLEPTIC-TZNAME:LMT
BEGIN:STANDARD
TZNAME:EET
TZOFFSETFROM:+020509
TZOFFSETTO:+0200
DTSTART:19001001T000000
END:STANDARD
BEGIN:DAYLIGHT
TZNAME:EEST
TZOFFSETFROM:+0200
TZOFFSETTO:+0300
DTSTART:19400715T000000
RDATE:19410415T000000

Timezone output is incorrect

Initially I thought only the output for Europe/London was incorrect. There is a rule for transition from DST to standard time, but the other rule (which should be standard to DST) has incorrect type, name, offsets (identical) and no RRULE (shortened for clarity):

BEGIN:VTIMEZONE
  BEGIN:STANDARD
    TZNAME:GMT
    TZOFFSETFROM:+0100
    TZOFFSETTO:+0000
    DTSTART:19701025T020000
    RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
  END:STANDARD
  BEGIN:STANDARD
    TZNAME:GMT
    TZOFFSETFROM:+0000
    TZOFFSETTO:+0000
    DTSTART:19700101T000000
  END:STANDARD
END:VTIMEZONE

It seems many (most) other timezones have issues as well. For instance America/Los_Angeles:

  • Has overlapping observances. All DTSTART values are in 1970, when I believe they should pick up where the previous observance rule ended.
  • Includes what seems to be a useless observance with the same offsets and no RRULE (like the second rule above).

It's hard to find exactly what change caused this as many of the commits lead to versions which can't parse the tzdata included in the same commit, but this seems to be quite old.

I wasn't able to make the tests complain about it, so either I don't run the way they're supposed to, or the tests are broken as well.

I'll try to isolate this further if I find the time, but if someone more familiar with the code can get a look it might be quicker.

Incompatibility with tzdata2019b

When building zoneinfo from tzdata2019b, the build fails with message Day overflow: 0:

root@59b14b244186:/mnt/vzic# make -B
make: Warning: File 'Makefile' has modification time 38 s in the future
cc -g -DOLSON_DIR=\"tzdata2019a\" -DPRODUCT_ID='"-//citadel.org//NONSGML Citadel calendar//EN"' -DTZID_PREFIX='"/citadel.org/%D_1/"' `pkg-config --cflags glib-2.0` -I/usr/local/include/libical -L/usr/local/lib64   -c -o vzic.o vzic.c
cc -g -DOLSON_DIR=\"tzdata2019a\" -DPRODUCT_ID='"-//citadel.org//NONSGML Citadel calendar//EN"' -DTZID_PREFIX='"/citadel.org/%D_1/"' `pkg-config --cflags glib-2.0` -I/usr/local/include/libical -L/usr/local/lib64   -c -o vzic-parse.o vzic-parse.c
cc -g -DOLSON_DIR=\"tzdata2019a\" -DPRODUCT_ID='"-//citadel.org//NONSGML Citadel calendar//EN"' -DTZID_PREFIX='"/citadel.org/%D_1/"' `pkg-config --cflags glib-2.0` -I/usr/local/include/libical -L/usr/local/lib64   -c -o vzic-dump.o vzic-dump.c
cc -g -DOLSON_DIR=\"tzdata2019a\" -DPRODUCT_ID='"-//citadel.org//NONSGML Citadel calendar//EN"' -DTZID_PREFIX='"/citadel.org/%D_1/"' `pkg-config --cflags glib-2.0` -I/usr/local/include/libical -L/usr/local/lib64   -c -o vzic-output.o vzic-output.c
cc vzic.o vzic-parse.o vzic-dump.o vzic-output.o `pkg-config --libs glib-2.0` -o vzic
make: warning:  Clock skew detected.  Your build may be incomplete.
root@59b14b244186:/mnt/vzic# ./vzic
WARNING: Asia/Shanghai: Modifying RRULE to be compatible with Outlook (day >= 11, month = 4)
ERROR: Asia/Shanghai: Couldn't modify RRULE to be compatible with Outlook (day >= 11, month = 4)
 ===> FAILING BACK TO PURE MODE THEN
WARNING: Asia/Shanghai: Modifying RRULE to be compatible with Outlook (day >= 11, month = 9)
ERROR: Asia/Shanghai: Couldn't modify RRULE to be compatible with Outlook (day >= 11, month = 9)
 ===> FAILING BACK TO PURE MODE THEN
Skipping DAYLIGHT change
WARNING: Asia/Tehran: Outputting BYDAY=3SU instead of BYMONTHDAY=15-21 for Outlook compatability
WARNING: Asia/Tehran: Outputting BYDAY=3SU instead of BYMONTHDAY=15-21 for Outlook compatability
WARNING: Asia/Baghdad: Outputting BYDAY=1SU instead of BYMONTHDAY=1-7 for Outlook compatability
WARNING: Asia/Baghdad: Outputting BYDAY=1SU instead of BYMONTHDAY=1-7 for Outlook compatability
WARNING: Asia/Baghdad: Outputting BYDAY=1SU instead of BYMONTHDAY=1-7 for Outlook compatability
Skipping DAYLIGHT change
WARNING: Asia/Baghdad: Outputting BYDAY=1SU instead of BYMONTHDAY=1-7 for Outlook compatability
Skipping DAYLIGHT change
Day overflow: 0

With tzdata2019a everything works as expected.

Europe/Moscow time zone file is incorrectly generated in Pure mode:

Looks like vzic ignores last timezone modification entry in "Pure" mode:

The last STANDARD section (in generated Moscow.ics) is:

BEGIN:STANDARD
TZOFFSETFROM:+0300                                                             
TZOFFSETTO:+0400                                                               
TZNAME:MSK
DTSTART:20110327T020000                                                        
RDATE:20110327T020000                                                          
END:STANDARD

But Europe/Moscow zone definition in Olson timezone file is

Zone Europe/Moscow       2:30:17 -      LMT     1880
                         2:30:17 -      MMT     1916 Jul  3 # Moscow Mean Time
                         2:31:19 Russia %s      1919 Jul  1  0:00u
                         3:00   Russia  %s      1921 Oct
                         3:00   Russia  MSK/MSD 1922 Oct
                         2:00   -       EET     1930 Jun 21
                         3:00   Russia  MSK/MSD 1991 Mar 31  2:00s
                         2:00   Russia  EE%sT   1992 Jan 19  2:00s
                         3:00   Russia  MSK/MSD 2011 Mar 27  2:00s
                         4:00   -       MSK     2014 Oct 26  2:00s
                         3:00   -       MSK

So there must be one more STANDARD section in generated file. This must look like:

BEGIN:STANDARD
TZOFFSETFROM:+0400                                                             
TZOFFSETTO:+0300                                                               
TZNAME:MSK
DTSTART:20141026T020000                                                        
RDATE:20141026T020000                                                          
END:STANDARD

“Zone description not found for: Etc/GMT-2” but output file Etc/GMT-2.ics looks good

Running vzic --pure --olson-dir tzdb-2019c --output-dir A prints

Zone description not found for: CET
Zone description not found for: CST6CDT
Zone description not found for: EET
Zone description not found for: EST
Zone description not found for: EST5EDT
Zone description not found for: Etc/GMT
Zone description not found for: Etc/GMT+1
Zone description not found for: Etc/GMT+10
Zone description not found for: Etc/GMT+11
Zone description not found for: Etc/GMT+12
Zone description not found for: Etc/GMT+2
Zone description not found for: Etc/GMT+3
Zone description not found for: Etc/GMT+4
Zone description not found for: Etc/GMT+5
Zone description not found for: Etc/GMT+6
Zone description not found for: Etc/GMT+7
Zone description not found for: Etc/GMT+8
Zone description not found for: Etc/GMT+9
Zone description not found for: Etc/GMT-1
Zone description not found for: Etc/GMT-10
Zone description not found for: Etc/GMT-11
Zone description not found for: Etc/GMT-12
Zone description not found for: Etc/GMT-13
Zone description not found for: Etc/GMT-14
Zone description not found for: Etc/GMT-2
Zone description not found for: Etc/GMT-3
Zone description not found for: Etc/GMT-4
Zone description not found for: Etc/GMT-5
Zone description not found for: Etc/GMT-6
Zone description not found for: Etc/GMT-7
Zone description not found for: Etc/GMT-8
Zone description not found for: Etc/GMT-9
Zone description not found for: Etc/UTC
Zone description not found for: HST
Zone description not found for: MET
Zone description not found for: MST
Zone description not found for: MST7MDT
Zone description not found for: PST8PDT
Zone description not found for: WET

but creates Etc/GMT-2.ics with content:

BEGIN:VCALENDAR
PRODID:-//citadel.org//NONSGML Citadel calendar//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:/citadel.org/20200311_1/Etc/GMT-2
LAST-MODIFIED:20200311T102343Z
X-LIC-LOCATION:Etc/GMT-2
X-PROLEPTIC-TZNAME:+02
BEGIN:STANDARD
TZNAME:+02
TZOFFSETFROM:+0200
TZOFFSETTO:+0200
DTSTART:16010101T000000
END:STANDARD
END:VTIMEZONE
END:VCALENDAR

It is unclear to me how to handle the error message from vzic, when the output seems correct.

Has vzic moved from soureforge to github.com/libical ?

The IANA Time Zone Database https://www.iana.org/time-zones publishes https://data.iana.org/time-zones/releases/tzdb-2019c.tar.lz (Complete Distribution (Data, Code and Extras)). Its tz-link.html contains:

<li><a href="https://sourceforge.net/projects/vzic/">Vzic</a> is a <a href="https://en.wikipedia.org/wiki/C_%28programming_language%29">C</a>
program that compiles<code><abbr>tz</abbr></code> source into iCalendar-compatible VTIMEZONE files.  Vzic is freely available under the <a href="https://www.gnu.org/copyleft/gpl.html"><abbr>GNU</abbr>General Public License (<abbr title="General Public License">GPL</abbr>)</a>.</li>

This states, that vzic can be downloaded from https://sourceforge.net/projects/vzic/ and the last published vzic 1.3 there is from 2006.

https://github.com/libical/vzic does make changes on vzic, but contains no releases.

Is the development of vzic was moved from sourceforge.net/projects/vzic to github.com/libical , then IANA shall be told to update its tz-link.html file.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.