The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl
use 5.012;
use lib 'blib/lib', 'blib/arch';

say "START";

my %WinToOlson = WinToOlson();

my ($max_win_len, $max_olson_len) = (0, 0);
my @tlist;
foreach my $win_name (sort keys %WinToOlson) {
    my $olson_name = $WinToOlson{$win_name};
	$max_win_len   = length($win_name)   if length($win_name)   > $max_win_len;
	$max_olson_len = length($olson_name) if length($olson_name) > $max_olson_len;
	push @tlist, qq#{"$win_name", "$olson_name"}#;
}

# for '\0'
$max_win_len++;
$max_olson_len++;

my $out = << "END";
struct win_tzpair {
    char win_name[$max_win_len];
    char olson_name[$max_olson_len];
};

END

$out .= "static win_tzpair translist[] = {\n";
$out .= "    ".join(",\n    ", @tlist);
$out .= "\n};";

say $out;

# This list comes (mostly) in the zipball for the Chronos project
# - a Smalltalk datetime library. Thanks, Chronos!
sub WinToOlson {(
	'Afghanistan'                     => 'Asia/Kabul',
	'Afghanistan Standard Time'       => 'Asia/Kabul',
	'Alaskan'                         => 'America/Anchorage',
	'Alaskan Standard Time'           => 'America/Anchorage',
	'Arab'                            => 'Asia/Riyadh',
	'Arab Standard Time'              => 'Asia/Riyadh',
	'Arabian'                         => 'Asia/Muscat',
	'Arabian Standard Time'           => 'Asia/Muscat',
	'Arabic Standard Time'            => 'Asia/Baghdad',
	'Argentina Standard Time'         => 'America/Argentina/Buenos_Aires',
	'Armenian Standard Time'          => 'Asia/Yerevan',
	'Atlantic'                        => 'America/Halifax',
	'Atlantic Standard Time'          => 'America/Halifax',
	'AUS Central'                     => 'Australia/Darwin',
	'AUS Central Standard Time'       => 'Australia/Darwin',
	'AUS Eastern'                     => 'Australia/Sydney',
	'AUS Eastern Standard Time'       => 'Australia/Sydney',
	'Azerbaijan Standard Time'        => 'Asia/Baku',
	'Azores'                          => 'Atlantic/Azores',
	'Azores Standard Time'            => 'Atlantic/Azores',
	'Bahia Standard Time'             => 'America/Bahia',
	'Bangkok'                         => 'Asia/Bangkok',
	'Bangkok Standard Time'           => 'Asia/Bangkok',
	'Bangladesh Standard Time'        => 'Asia/Dhaka',
	'Beijing'                         => 'Asia/Shanghai',
	'Canada Central'                  => 'America/Regina',
	'Canada Central Standard Time'    => 'America/Regina',
	'Cape Verde Standard Time'        => 'Atlantic/Cape_Verde',
	'Caucasus'                        => 'Asia/Yerevan',
	'Caucasus Standard Time'          => 'Asia/Yerevan',
	'Cen. Australia'                  => 'Australia/Adelaide',
	'Cen. Australia Standard Time'    => 'Australia/Adelaide',
	'Central'                         => 'America/Chicago',
	'Central America Standard Time'   => 'America/Regina',
	'Central Asia'                    => 'Asia/Almaty',
	'Central Asia Standard Time'      => 'Asia/Almaty',
	'Central Brazilian Standard Time' => 'America/Cuiaba',
	'Central Europe'                  => 'Europe/Prague',
	'Central Europe Standard Time'    => 'Europe/Prague',
	'Central European'                => 'Europe/Belgrade',
	'Central European Standard Time'  => 'Europe/Belgrade',
	'Central Pacific'                 => 'Pacific/Guadalcanal',
	'Central Pacific Standard Time'   => 'Pacific/Guadalcanal',
	'Central Standard Time'           => 'America/Chicago',
	'Central Standard Time (Mexico)'  => 'America/Mexico_City',
	'China'                           => 'Asia/Shanghai',
	'China Standard Time'             => 'Asia/Shanghai',
	'Dateline'                        => 'UTC-12',
	'Dateline Standard Time'          => 'UTC-12',
	'E. Africa'                       => 'Africa/Nairobi',
	'E. Africa Standard Time'         => 'Africa/Nairobi',
	'E. Australia'                    => 'Australia/Brisbane',
	'E. Australia Standard Time'      => 'Australia/Brisbane',
	'E. Europe'                       => 'Europe/Minsk',
	'E. Europe Standard Time'         => 'Europe/Minsk',
	'E. South America'                => 'America/Sao_Paulo',
	'E. South America Standard Time'  => 'America/Sao_Paulo',
	'Eastern'                         => 'America/New_York',
	'Eastern Standard Time'           => 'America/New_York',
	'Egypt'                           => 'Africa/Cairo',
	'Egypt Standard Time'             => 'Africa/Cairo',
	'Ekaterinburg'                    => 'Asia/Yekaterinburg',
	'Ekaterinburg Standard Time'      => 'Asia/Yekaterinburg',
	'Fiji'                            => 'Pacific/Fiji',
	'Fiji Standard Time'              => 'Pacific/Fiji',
	'FLE'                             => 'Europe/Helsinki',
	'FLE Standard Time'               => 'Europe/Helsinki',
	'Georgian Standard Time'          => 'Asia/Tbilisi',
	'GFT'                             => 'Europe/Athens',
	'GFT Standard Time'               => 'Europe/Athens',
	'GMT'                             => 'Europe/London',
	'GMT Standard Time'               => 'Europe/London',
	'Greenland Standard Time'         => 'America/Godthab',
	'Greenwich'                       => 'GMT',
	'Greenwich Standard Time'         => 'GMT',
	'GTB'                             => 'Europe/Athens',
	'GTB Standard Time'               => 'Europe/Athens',
	'Hawaiian'                        => 'Pacific/Honolulu',
	'Hawaiian Standard Time'          => 'Pacific/Honolulu',
	'India'                           => 'Asia/Calcutta',
	'India Standard Time'             => 'Asia/Calcutta',
	'Iran'                            => 'Asia/Tehran',
	'Iran Standard Time'              => 'Asia/Tehran',
	'Israel'                          => 'Asia/Jerusalem',
	'Israel Standard Time'            => 'Asia/Jerusalem',
	'Jordan Standard Time'            => 'Asia/Amman',
	'Kaliningrad Standard Time'       => 'Europe/Kaliningrad',
	'Kamchatka Standard Time'         => 'Asia/Kamchatka',
	'Korea'                           => 'Asia/Seoul',
	'Korea Standard Time'             => 'Asia/Seoul',
	'Magadan Standard Time'           => 'Asia/Magadan',
	'Mauritius Standard Time'         => 'Indian/Mauritius',
	'Mexico'                          => 'America/Mexico_City',
	'Mexico Standard Time'            => 'America/Mexico_City',
	'Mexico Standard Time 2'          => 'America/Chihuahua',
	'Mid-Atlantic'                    => 'Atlantic/South_Georgia',
	'Mid-Atlantic Standard Time'      => 'Atlantic/South_Georgia',
	'Middle East Standard Time'       => 'Asia/Beirut',
	'Montevideo Standard Time'        => 'America/Montevideo',
	'Morocco Standard Time'           => 'Africa/Casablanca',
	'Mountain'                        => 'America/Denver',
	'Mountain Standard Time'          => 'America/Denver',
	'Mountain Standard Time (Mexico)' => 'America/Chihuahua',
	'Myanmar Standard Time'           => 'Asia/Rangoon',
	'N. Central Asia Standard Time'   => 'Asia/Novosibirsk',
	'Namibia Standard Time'           => 'Africa/Windhoek',
	'Nepal Standard Time'             => 'Asia/Katmandu',
	'New Zealand'                     => 'Pacific/Auckland',
	'New Zealand Standard Time'       => 'Pacific/Auckland',
	'Newfoundland'                    => 'America/St_Johns',
	'Newfoundland Standard Time'      => 'America/St_Johns',
	'North Asia East Standard Time'   => 'Asia/Irkutsk',
	'North Asia Standard Time'        => 'Asia/Krasnoyarsk',
	'Pacific'                         => 'America/Los_Angeles',
	'Pacific SA'                      => 'America/Santiago',
	'Pacific SA Standard Time'        => 'America/Santiago',
	'Pacific Standard Time'           => 'America/Los_Angeles',
	'Pacific Standard Time (Mexico)'  => 'America/Tijuana',
	'Pakistan Standard Time'          => 'Asia/Karachi',
	'Paraguay Standard Time'          => 'America/Asuncion',
	'Prague Bratislava'               => 'Europe/Prague',
	'Romance'                         => 'Europe/Paris',
	'Romance Standard Time'           => 'Europe/Paris',
	'Russian'                         => 'Europe/Moscow',
	'Russian Standard Time'           => 'Europe/Moscow',
	'SA Eastern'                      => 'America/Cayenne',
	'SA Eastern Standard Time'        => 'America/Cayenne',
	'SA Pacific'                      => 'America/Bogota',
	'SA Pacific Standard Time'        => 'America/Bogota',
	'SA Western'                      => 'America/Guyana',
	'SA Western Standard Time'        => 'America/Guyana',
	'Samoa'                           => 'Pacific/Apia',
	'Samoa Standard Time'             => 'Pacific/Apia',
	'Saudi Arabia'                    => 'Asia/Riyadh',
	'Saudi Arabia Standard Time'      => 'Asia/Riyadh',
	'SE Asia'                         => 'Asia/Bangkok',
	'SE Asia Standard Time'           => 'Asia/Bangkok',
	'Singapore'                       => 'Asia/Singapore',
	'Singapore Standard Time'         => 'Asia/Singapore',
	'South Africa'                    => 'Africa/Harare',
	'South Africa Standard Time'      => 'Africa/Harare',
	'Sri Lanka'                       => 'Asia/Colombo',
	'Sri Lanka Standard Time'         => 'Asia/Colombo',
	'Syria Standard Time'             => 'Asia/Damascus',
	'Sydney Standard Time'            => 'Australia/Sydney',
	'Taipei'                          => 'Asia/Taipei',
	'Taipei Standard Time'            => 'Asia/Taipei',
	'Tasmania'                        => 'Australia/Hobart',
	'Tasmania Standard Time'          => 'Australia/Hobart',
	'Tokyo'                           => 'Asia/Tokyo',
	'Tokyo Standard Time'             => 'Asia/Tokyo',
	'Tonga Standard Time'             => 'Pacific/Tongatapu',
	'Turkey Standard Time'            => 'Europe/Istanbul',
	'Ulaanbaatar Standard Time'       => 'Asia/Ulaanbaatar',
	'US Eastern'                      => 'America/Indianapolis',
	'US Eastern Standard Time'        => 'America/Indianapolis',
	'US Mountain'                     => 'America/Phoenix',
	'US Mountain Standard Time'       => 'America/Phoenix',
	'UTC'                             => 'UTC',
	'UTC+12'                          => 'UTC+12',
	'UTC-02'                          => 'UTC-2',
	'UTC-11'                          => 'UTC-11',
	'Venezuela Standard Time'         => 'America/Caracas',
	'Vladivostok'                     => 'Asia/Vladivostok',
	'Vladivostok Standard Time'       => 'Asia/Vladivostok',
	'W. Australia'                    => 'Australia/Perth',
	'W. Australia Standard Time'      => 'Australia/Perth',
	'W. Central Africa Standard Time' => 'Africa/Luanda',
	'W. Europe'                       => 'Europe/Berlin',
	'W. Europe Standard Time'         => 'Europe/Berlin',
	'Warsaw'                          => 'Europe/Warsaw',
	'West Asia'                       => 'Asia/Karachi',
	'West Asia Standard Time'         => 'Asia/Karachi',
	'West Pacific'                    => 'Pacific/Guam',
	'West Pacific Standard Time'      => 'Pacific/Guam',
	'Western Brazilian Standard Time' => 'America/Rio_Branco',
	'Yakutsk'                         => 'Asia/Yakutsk',
	'Yakutsk Standard Time'           => 'Asia/Yakutsk',
)}

1;