This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
I sometimes outsmart myself.
[perl5.git] / lib / Locale / Country.pm
1 #-----------------------------------------------------------------------
2
3 =head1 NAME
4
5 Locale::Country - ISO codes for country identification (ISO 3166)
6
7 =head1 SYNOPSIS
8
9     use Locale::Country;
10     
11     $country = code2country('jp');               # $country gets 'Japan'
12     $code    = country2code('Norway');           # $code gets 'no'
13     
14     @codes   = all_country_codes();
15     @names   = all_country_names();
16     
17     # add "uk" as a pseudo country code for United Kingdom
18     Locale::Country::_alias_code('uk' => 'gb');
19
20 =cut
21
22 #-----------------------------------------------------------------------
23
24 package Locale::Country;
25 use strict;
26 require 5.002;
27
28 #-----------------------------------------------------------------------
29
30 =head1 DESCRIPTION
31
32 The C<Locale::Country> module provides access to the ISO
33 codes for identifying countries, as defined in ISO 3166.
34 You can either access the codes via the L<conversion routines>
35 (described below), or with the two functions which return lists
36 of all country codes or all country names.
37
38 There are three different code sets you can use for identifying
39 countries:
40
41 =over 4
42
43 =item B<alpha-2>
44
45 Two letter codes, such as 'tv' for Tuvalu.
46 This code set is identified with the symbol C<LOCALE_CODE_ALPHA_2>.
47
48 =item B<alpha-3>
49
50 Three letter codes, such as 'brb' for Barbados.
51 This code set is identified with the symbol C<LOCALE_CODE_ALPHA_3>.
52
53 =item B<numeric>
54
55 Numeric codes, such as 064 for Bhutan.
56 This code set is identified with the symbol C<LOCALE_CODE_NUMERIC>.
57
58 =back
59
60 All of the routines take an optional additional argument
61 which specifies the code set to use.
62 If not specified, it defaults to the two-letter codes.
63 This is partly for backwards compatibility (previous versions
64 of this module only supported the alpha-2 codes), and
65 partly because they are the most widely used codes.
66
67 The alpha-2 and alpha-3 codes are not case-dependent,
68 so you can use 'BO', 'Bo', 'bO' or 'bo' for Bolivia.
69 When a code is returned by one of the functions in
70 this module, it will always be lower-case.
71
72 =cut
73
74 #-----------------------------------------------------------------------
75
76 require Exporter;
77 use Carp;
78 use Locale::Constants;
79
80
81 #-----------------------------------------------------------------------
82 #       Public Global Variables
83 #-----------------------------------------------------------------------
84 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
85 $VERSION   = sprintf("%d.%02d", q$Revision: 1.7 $ =~ /(\d+)\.(\d+)/);
86 @ISA       = qw(Exporter);
87 @EXPORT    = qw(code2country country2code
88                 all_country_codes all_country_names
89                 country_code2code
90                 LOCALE_CODE_ALPHA_2 LOCALE_CODE_ALPHA_3 LOCALE_CODE_NUMERIC);
91
92 #-----------------------------------------------------------------------
93 #       Private Global Variables
94 #-----------------------------------------------------------------------
95 my $CODES     = [];
96 my $COUNTRIES = [];
97
98
99 #=======================================================================
100
101 =head1 CONVERSION ROUTINES
102
103 There are three conversion routines: C<code2country()>, C<country2code()>,
104 and C<country_code2code()>.
105
106 =over 8
107
108 =item code2country( CODE, [ CODESET ] )
109
110 This function takes a country code and returns a string
111 which contains the name of the country identified.
112 If the code is not a valid country code, as defined by ISO 3166,
113 then C<undef> will be returned:
114
115     $country = code2country('fi');
116
117 =item country2code( STRING, [ CODESET ] )
118
119 This function takes a country name and returns the corresponding
120 country code, if such exists.
121 If the argument could not be identified as a country name,
122 then C<undef> will be returned:
123
124     $code = country2code('Norway', LOCALE_CODE_ALPHA_3);
125     # $code will now be 'nor'
126
127 The case of the country name is not important.
128 See the section L<KNOWN BUGS AND LIMITATIONS> below.
129
130 =item country_code2code( CODE, CODESET, CODESET )
131
132 This function takes a country code from one code set,
133 and returns the corresponding code from another code set.
134
135     $alpha2 = country_code2code('fin',
136                  LOCALE_CODE_ALPHA_3 => LOCALE_CODE_ALPHA_2);
137     # $alpha2 will now be 'fi'
138
139 If the code passed is not a valid country code in
140 the first code set, or if there isn't a code for the
141 corresponding country in the second code set,
142 then C<undef> will be returned.
143
144 =back
145
146 =cut
147
148 #=======================================================================
149 sub code2country
150 {
151     my $code = shift;
152     my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
153
154
155     return undef unless defined $code;
156
157     #-------------------------------------------------------------------
158     # Make sure the code is in the right form before we use it
159     # to look up the corresponding country.
160     # We have to sprintf because the codes are given as 3-digits,
161     # with leading 0's. Eg 052 for Barbados.
162     #-------------------------------------------------------------------
163     if ($codeset == LOCALE_CODE_NUMERIC)
164     {
165         return undef if ($code =~ /\D/);
166         $code = sprintf("%.3d", $code);
167     }
168     else
169     {
170         $code = lc($code);
171     }
172
173     if (exists $CODES->[$codeset]->{$code})
174     {
175         return $CODES->[$codeset]->{$code};
176     }
177     else
178     {
179         #---------------------------------------------------------------
180         # no such country code!
181         #---------------------------------------------------------------
182         return undef;
183     }
184 }
185
186 sub country2code
187 {
188     my $country = shift;
189     my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
190
191
192     return undef unless defined $country;
193     $country = lc($country);
194     if (exists $COUNTRIES->[$codeset]->{$country})
195     {
196         return $COUNTRIES->[$codeset]->{$country};
197     }
198     else
199     {
200         #---------------------------------------------------------------
201         # no such country!
202         #---------------------------------------------------------------
203         return undef;
204     }
205 }
206
207 sub country_code2code
208 {
209     (@_ == 3) or croak "country_code2code() takes 3 arguments!";
210
211     my $code = shift;
212     my $inset = shift;
213     my $outset = shift;
214     my $outcode = shift;
215     my $country;
216
217
218     return undef if $inset == $outset;
219     $country = code2country($code, $inset);
220     return undef if not defined $country;
221     $outcode = country2code($country, $outset);
222     return $outcode;
223 }
224
225 #=======================================================================
226
227 =head1 QUERY ROUTINES
228
229 There are two function which can be used to obtain a list of all codes,
230 or all country names:
231
232 =over 8
233
234 =item C<all_country_codes( [ CODESET ] )>
235
236 Returns a list of all two-letter country codes.
237 The codes are guaranteed to be all lower-case,
238 and not in any particular order.
239
240 =item C<all_country_names( [ CODESET ] )>
241
242 Returns a list of all country names for which there is a corresponding
243 country code in the specified code set.
244 The names are capitalised, and not returned in any particular order.
245
246 Not all countries have alpha-3 and numeric codes -
247 some just have an alpha-2 code,
248 so you'll get a different number of countries
249 depending on which code set you specify.
250
251 =back
252
253 =cut
254
255 #=======================================================================
256 sub all_country_codes
257 {
258     my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
259
260     return keys %{ $CODES->[$codeset] };
261 }
262
263 sub all_country_names
264 {
265     my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
266
267     return values %{ $CODES->[$codeset] };
268 }
269
270 #-----------------------------------------------------------------------
271
272 =head1 CODE ALIASING
273
274 This module supports a semi-private routine for specifying two letter
275 code aliases.
276
277     Locale::Country::_alias_code( ALIAS => CODE [, CODESET ] )
278
279 This feature was added as a mechanism for handling
280 a "uk" code. The ISO standard says that the two-letter code for
281 "United Kingdom" is "gb", whereas domain names are all .uk.
282
283 By default the module does not understand "uk", since it is implementing
284 an ISO standard. If you would like 'uk' to work as the two-letter
285 code for United Kingdom, use the following:
286
287     use Locale::Country;
288     
289     Locale::Country::_alias_code('uk' => 'gb');
290
291 With this code, both "uk" and "gb" are valid codes for United Kingdom,
292 with the reverse lookup returning "uk" rather than the usual "gb".
293
294 =cut
295
296 #-----------------------------------------------------------------------
297
298 sub _alias_code
299 {
300     my $alias = shift;
301     my $real  = shift;
302     my $codeset = @_ > 0 ? shift : LOCALE_CODE_DEFAULT;
303
304     my $country;
305
306
307     if (not exists $CODES->[$codeset]->{$real})
308     {
309         carp "attempt to alias \"$alias\" to unknown country code \"$real\"\n";
310         return undef;
311     }
312     $country = $CODES->[$codeset]->{$real};
313     $CODES->[$codeset]->{$alias} = $country;
314     $COUNTRIES->[$codeset]->{"\L$country"} = $alias;
315
316     return $alias;
317 }
318
319 #-----------------------------------------------------------------------
320
321 =head1 EXAMPLES
322
323 The following example illustrates use of the C<code2country()> function.
324 The user is prompted for a country code, and then told the corresponding
325 country name:
326
327     $| = 1;   # turn off buffering
328     
329     print "Enter country code: ";
330     chop($code = <STDIN>);
331     $country = code2country($code, LOCALE_CODE_ALPHA_2);
332     if (defined $country)
333     {
334         print "$code = $country\n";
335     }
336     else
337     {
338         print "'$code' is not a valid country code!\n";
339     }
340
341 =head1 DOMAIN NAMES
342
343 Most top-level domain names are based on these codes,
344 but there are certain codes which aren't.
345 If you are using this module to identify country from hostname,
346 your best bet is to preprocess the country code.
347
348 For example, B<edu>, B<com>, B<gov> and friends would map to B<us>;
349 B<uk> would map to B<gb>. Any others?
350
351 =head1 KNOWN BUGS AND LIMITATIONS
352
353 =over 4
354
355 =item *
356
357 When using C<country2code()>, the country name must currently appear
358 exactly as it does in the source of the module. For example,
359
360     country2code('United States')
361
362 will return B<us>, as expected. But the following will all return C<undef>:
363
364     country2code('United States of America')
365     country2code('Great Britain')
366     country2code('U.S.A.')
367
368 If there's need for it, a future version could have variants
369 for country names.
370
371 =item *
372
373 In the current implementation, all data is read in when the
374 module is loaded, and then held in memory.
375 A lazy implementation would be more memory friendly.
376
377 =back
378
379 =head1 SEE ALSO
380
381 =over 4
382
383 =item Locale::Language
384
385 ISO two letter codes for identification of language (ISO 639).
386
387 =item Locale::Currency
388
389 ISO three letter codes for identification of currencies
390 and funds (ISO 4217).
391
392 =item ISO 3166
393
394 The ISO standard which defines these codes.
395
396 =item http://www.din.de/gremien/nas/nabd/iso3166ma/
397
398 Official home page for ISO 3166
399
400 =item http://www.egt.ie/standards/iso3166/iso3166-1-en.html
401
402 Another useful, but not official, home page.
403
404 =item http://www.cia.gov/cia/publications/factbook/docs/app-f.html
405
406 An appendix in the CIA world fact book which lists country codes
407 as defined by ISO 3166, FIPS 10-4, and internet domain names.
408
409 =back
410
411
412 =head1 AUTHOR
413
414 Neil Bowers E<lt>neilb@cre.canon.co.ukE<gt>
415
416 =head1 COPYRIGHT
417
418 Copyright (c) 1997-2001 Canon Research Centre Europe (CRE).
419
420 This module is free software; you can redistribute it and/or
421 modify it under the same terms as Perl itself.
422
423 =cut
424
425 #-----------------------------------------------------------------------
426
427 #=======================================================================
428 # initialisation code - stuff the DATA into the ALPHA2 hash
429 #=======================================================================
430 {
431     my ($alpha2, $alpha3, $numeric);
432     my $country;
433
434
435     while (<DATA>)
436     {
437         next unless /\S/;
438         chop;
439         ($alpha2, $alpha3, $numeric, $country) = split(/:/, $_, 4);
440
441         $CODES->[LOCALE_CODE_ALPHA_2]->{$alpha2} = $country;
442         $COUNTRIES->[LOCALE_CODE_ALPHA_2]->{"\L$country"} = $alpha2;
443
444         if ($alpha3)
445         {
446             $CODES->[LOCALE_CODE_ALPHA_3]->{$alpha3} = $country;
447             $COUNTRIES->[LOCALE_CODE_ALPHA_3]->{"\L$country"} = $alpha3;
448         }
449
450         if ($numeric)
451         {
452             $CODES->[LOCALE_CODE_NUMERIC]->{$numeric} = $country;
453             $COUNTRIES->[LOCALE_CODE_NUMERIC]->{"\L$country"} = $numeric;
454         }
455
456     }
457 }
458
459 1;
460
461 __DATA__
462 ad:and:020:Andorra
463 ae:are:784:United Arab Emirates
464 af:afg:004:Afghanistan
465 ag:atg:028:Antigua and Barbuda
466 ai:aia:660:Anguilla
467 al:alb:008:Albania
468 am:arm:051:Armenia
469 an:ant:530:Netherlands Antilles
470 ao:ago:024:Angola
471 aq:::Antarctica
472 ar:arg:032:Argentina
473 as:asm:016:American Samoa
474 at:aut:040:Austria
475 au:aus:036:Australia
476 aw:abw:533:Aruba
477 az:aze:031:Azerbaijan
478 ba:bih:070:Bosnia and Herzegovina
479 bb:brb:052:Barbados
480 bd:bgd:050:Bangladesh
481 be:bel:056:Belgium
482 bf:bfa:854:Burkina Faso
483 bg:bgr:100:Bulgaria
484 bh:bhr:048:Bahrain
485 bi:bdi:108:Burundi
486 bj:ben:204:Benin
487 bm:bmu:060:Bermuda
488 bn:brn:096:Brunei Darussalam
489 bo:bol:068:Bolivia
490 br:bra:076:Brazil
491 bs:bhs:044:Bahamas
492 bt:btn:064:Bhutan
493 bv:::Bouvet Island
494 bw:bwa:072:Botswana
495 by:blr:112:Belarus
496 bz:blz:084:Belize
497 ca:can:124:Canada
498 cc:::Cocos (Keeling) Islands
499 cd:cod:180:Congo, The Democratic Republic of the
500 cf:caf:140:Central African Republic
501 cg:cog:178:Congo
502 ch:che:756:Switzerland
503 ci:civ:384:Cote D'Ivoire
504 ck:cok:184:Cook Islands
505 cl:chl:152:Chile
506 cm:cmr:120:Cameroon
507 cn:chn:156:China
508 co:col:170:Colombia
509 cr:cri:188:Costa Rica
510 cu:cub:192:Cuba
511 cv:cpv:132:Cape Verde
512 cx:::Christmas Island
513 cy:cyp:196:Cyprus
514 cz:cze:203:Czech Republic
515 de:deu:276:Germany
516 dj:dji:262:Djibouti
517 dk:dnk:208:Denmark
518 dm:dma:212:Dominica
519 do:dom:214:Dominican Republic
520 dz:dza:012:Algeria
521 ec:ecu:218:Ecuador
522 ee:est:233:Estonia
523 eg:egy:818:Egypt
524 eh:esh:732:Western Sahara
525 er:eri:232:Eritrea
526 es:esp:724:Spain
527 et:eth:231:Ethiopia
528 fi:fin:246:Finland
529 fj:fji:242:Fiji
530 fk:flk:238:Falkland Islands (Malvinas)
531 fm:fsm:583:Micronesia, Federated States of
532 fo:fro:234:Faroe Islands
533 fr:fra:250:France
534 fx:::France, Metropolitan
535 ga:gab:266:Gabon
536 gb:gbr:826:United Kingdom
537 gd:grd:308:Grenada
538 ge:geo:268:Georgia
539 gf:guf:254:French Guiana
540 gh:gha:288:Ghana
541 gi:gib:292:Gibraltar
542 gl:grl:304:Greenland
543 gm:gmb:270:Gambia
544 gn:gin:324:Guinea
545 gp:glp:312:Guadeloupe
546 gq:gnq:226:Equatorial Guinea
547 gr:grc:300:Greece
548 gs:::South Georgia and the South Sandwich Islands
549 gt:gtm:320:Guatemala
550 gu:gum:316:Guam
551 gw:gnb:624:Guinea-Bissau
552 gy:guy:328:Guyana
553 hk:hkg:344:Hong Kong
554 hm:::Heard Island and McDonald Islands
555 hn:hnd:340:Honduras
556 hr:hrv:191:Croatia
557 ht:hti:332:Haiti
558 hu:hun:348:Hungary
559 id:idn:360:Indonesia
560 ie:irl:372:Ireland
561 il:isr:376:Israel
562 in:ind:356:India
563 io:::British Indian Ocean Territory
564 iq:irq:368:Iraq
565 ir:irn:364:Iran, Islamic Republic of
566 is:isl:352:Iceland
567 it:ita:380:Italy
568 jm:jam:388:Jamaica
569 jo:jor:400:Jordan
570 jp:jpn:392:Japan
571 ke:ken:404:Kenya
572 kg:kgz:417:Kyrgyzstan
573 kh:khm:116:Cambodia
574 ki:kir:296:Kiribati
575 km:com:174:Comoros
576 kn:kna:659:Saint Kitts and Nevis
577 kp:prk:408:Korea, Democratic People's Republic of
578 kr:kor:410:Korea, Republic of
579 kw:kwt:414:Kuwait
580 ky:cym:136:Cayman Islands
581 kz:kaz:398:Kazakstan
582 la:lao:418:Lao People's Democratic Republic
583 lb:lbn:422:Lebanon
584 lc:lca:662:Saint Lucia
585 li:lie:438:Liechtenstein
586 lk:lka:144:Sri Lanka
587 lr:lbr:430:Liberia
588 ls:lso:426:Lesotho
589 lt:ltu:440:Lithuania
590 lu:lux:442:Luxembourg
591 lv:lva:428:Latvia
592 ly:lby:434:Libyan Arab Jamahiriya
593 ma:mar:504:Morocco
594 mc:mco:492:Monaco
595 md:mda:498:Moldova, Republic of
596 mg:mdg:450:Madagascar
597 mh:mhl:584:Marshall Islands
598 mk:mkd:807:Macedonia, the Former Yugoslav Republic of
599 ml:mli:466:Mali
600 mm:mmr:104:Myanmar
601 mn:mng:496:Mongolia
602 mo:mac:446:Macau
603 mp:mnp:580:Northern Mariana Islands
604 mq:mtq:474:Martinique
605 mr:mrt:478:Mauritania
606 ms:msr:500:Montserrat
607 mt:mlt:470:Malta
608 mu:mus:480:Mauritius
609 mv:mdv:462:Maldives
610 mw:mwi:454:Malawi
611 mx:mex:484:Mexico
612 my:mys:458:Malaysia
613 mz:moz:508:Mozambique
614 na:nam:516:Namibia
615 nc:ncl:540:New Caledonia
616 ne:ner:562:Niger
617 nf:nfk:574:Norfolk Island
618 ng:nga:566:Nigeria
619 ni:nic:558:Nicaragua
620 nl:nld:528:Netherlands
621 no:nor:578:Norway
622 np:npl:524:Nepal
623 nr:nru:520:Nauru
624 nu:niu:570:Niue
625 nz:nzl:554:New Zealand
626 om:omn:512:Oman
627 pa:pan:591:Panama
628 pe:per:604:Peru
629 pf:pyf:258:French Polynesia
630 pg:png:598:Papua New Guinea
631 ph:phl:608:Philippines
632 pk:pak:586:Pakistan
633 pl:pol:616:Poland
634 pm:spm:666:Saint Pierre and Miquelon
635 pn:pcn:612:Pitcairn
636 pr:pri:630:Puerto Rico
637 ps:pse:275:Palestinian Territory, Occupied
638 pt:prt:620:Portugal
639 pw:plw:585:Palau
640 py:pry:600:Paraguay
641 qa:qat:634:Qatar
642 re:reu:638:Reunion
643 ro:rom:642:Romania
644 ru:rus:643:Russian Federation
645 rw:rwa:646:Rwanda
646 sa:sau:682:Saudi Arabia
647 sb:slb:090:Solomon Islands
648 sc:syc:690:Seychelles
649 sd:sdn:736:Sudan
650 se:swe:752:Sweden
651 sg:sgp:702:Singapore
652 sh:shn:654:Saint Helena
653 si:svn:705:Slovenia
654 sj:sjm:744:Svalbard and Jan Mayen
655 sk:svk:703:Slovakia
656 sl:sle:694:Sierra Leone
657 sm:smr:674:San Marino
658 sn:sen:686:Senegal
659 so:som:706:Somalia
660 sr:sur:740:Suriname
661 st:stp:678:Sao Tome and Principe
662 sv:slv:222:El Salvador
663 sy:syr:760:Syrian Arab Republic
664 sz:swz:748:Swaziland
665 tc:tca:796:Turks and Caicos Islands
666 td:tcd:148:Chad
667 tf:::French Southern Territories
668 tg:tgo:768:Togo
669 th:tha:764:Thailand
670 tj:tjk:762:Tajikistan
671 tk:tkl:772:Tokelau
672 tm:tkm:795:Turkmenistan
673 tn:tun:788:Tunisia
674 to:ton:776:Tonga
675 tp:tmp:626:East Timor
676 tr:tur:792:Turkey
677 tt:tto:780:Trinidad and Tobago
678 tv:tuv:798:Tuvalu
679 tw:twn:158:Taiwan, Province of China
680 tz:tza:834:Tanzania, United Republic of
681 ua:ukr:804:Ukraine
682 ug:uga:800:Uganda
683 um:::United States Minor Outlying Islands
684 us:usa:840:United States
685 uy:ury:858:Uruguay
686 uz:uzb:860:Uzbekistan
687 va:vat:336:Holy See (Vatican City State)
688 vc:vct:670:Saint Vincent and the Grenadines
689 ve:ven:862:Venezuela
690 vg:vgb:092:Virgin Islands, British
691 vi:vir:850:Virgin Islands, U.S.
692 vn:vnm:704:Vietnam
693 vu:vut:548:Vanuatu
694 wf:wlf:876:Wallis and Futuna
695 ws:wsm:882:Samoa
696 ye:yem:887:Yemen
697 yt:::Mayotte
698 yu:yug:891:Yugoslavia
699 za:zaf:710:South Africa
700 zm:zmb:894:Zambia
701 zr:::Zaire
702 zw:zwe:716:Zimbabwe