#!/usr/bin/perl -w # # Vzic - a program to convert Olson timezone database files into VZTIMEZONE # files compatible with the iCalendar specification (RFC2445). # # Copyright (C) 2001 Ximian, Inc. # Copyright (C) 2003 Damon Chaplin. # # Author: Damon Chaplin # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # # This outputs an iCalendar file containing one event in each timezone, # as well as all the VTIMEZONEs. We use it for testing compatability with # other iCalendar apps like Outlook, by trying to import it there. # # Currently we have 377 timezones (with tzdata2001d). # # Set this to the toplevel directory of the VTIMEZONE files. $ZONEINFO_DIR = "/home/damon/src/zoneinfo"; $output_file = "calendar.ics"; # Save this so we can restore it later. $input_record_separator = $/; chdir $ZONEINFO_DIR || die "Can't cd to $ZONEINFO_DIR"; # Create the output file, to contain all the VEVENTs & VTIMEZONEs. open (OUTPUTFILE, ">$output_file") || die "Can't create file: $output_file"; # Output the standard header. print OUTPUTFILE <; $/ = $input_record_separator; close (ZONEFILE); # Strip the stuff before and after the VTIMEZONE component $vtimezone =~ s/^.*BEGIN:VTIMEZONE/BEGIN:VTIMEZONE/s; $vtimezone =~ s/END:VTIMEZONE.*$/END:VTIMEZONE\n/s; print OUTPUTFILE $vtimezone; # Find the TZID. $vtimezone =~ m/TZID:(.*)/; $tzid = $1; # print "TZID: $tzid\n"; # Find the location. $file =~ m/(.*)\.ics/; $location = $1; # print "LOCATION: $location\n"; # Try to find the current UTC offset that Outlook will use. # If there is an RRULE, we look for the first 2 TZOFFSETTO properties, # else we just get the first one. if ($vtimezone =~ m/RRULE/) { $vtimezone =~ m/TZOFFSETTO:([+-]?\d+)/; $tzoffsetto = $1; $vtimezone =~ m/TZOFFSETFROM:([+-]?\d+)/; $tzoffsetfrom = $1; $tzoffset = "$tzoffsetfrom/$tzoffsetto"; } else { $vtimezone =~ m/TZOFFSETTO:([+-]?\d+)/s; $tzoffset = $1; } # print "TZOFFSET: $tzoffset\n"; # We put each event on a separate day in 2001 and Jan 2002. $day_num = $zone_num; if ($day_num >= 365) { $year = 2002; $day_num -= 365; } else { $year = 2001; } $month = -1; for ($i = 0; $i < 12; $i++) { if ($day_num < $days_in_month[$i]) { $month = $i; last; } $day_num -= $days_in_month[$i] } if ($month == -1) { die "month = -1"; } $month++; $day_num++; $date = sprintf ("%i%02i%02i", $year, $month, $day_num); # print "Date: $date\n"; # Output a VEVENT using the timezone. print OUTPUTFILE <