File Coverage

lib/Locale/Unicode.pm
Criterion Covered Total %
statement 579 861 67.2
branch 181 396 45.7
condition 127 384 33.0
subroutine 131 211 62.0
pod 119 125 95.2
total 1137 1977 57.5


line stmt bran cond sub pod time code
1             ##----------------------------------------------------------------------------
2             ## Unicode Locale Identifier - ~/lib/Locale/Unicode.pm
3             ## Version v0.4.0
4             ## Copyright(c) 2025 DEGUEST Pte. Ltd.
5             ## Author: Jacques Deguest <jack@deguest.jp>
6             ## Created 2024/05/11
7             ## Modified 2025/10/16
8             ## All rights reserved
9             ##
10             ##
11             ## This program is free software; you can redistribute it and/or modify it
12             ## under the same terms as Perl itself.
13             ##----------------------------------------------------------------------------
14             package Locale::Unicode;
15             BEGIN
16             {
17 3     3   386935 use v5.10.1;
  3         10  
18 3     3   16 use strict;
  3         5  
  3         118  
19 3     3   30 use warnings;
  3         11  
  3         192  
20 3     3   17 use warnings::register;
  3         7  
  3         300  
21 3         502 use vars qw(
22             $ERROR $VERSION $DEBUG $FATAL_EXCEPTIONS
23             $LOCALE_BCP47_RE $LOCALE_BCP47_NAMELESS_RE $LOCALE_RE $LOCALE_UNICODE_SUBTAG_RE
24             $LOCALE_EXTENSIONS_RE $LOCALE_TRANSFORM_PARAMETERS_RE $GRANDFATHERED_IRREGULAR
25             $GRANDFATHERED_REGULAR
26             $TZ_DICT $TZ_NAME2ID
27             $PROP_TO_SUB
28             $EXPLICIT_BOOLEAN
29 3     3   15 );
  3         11  
30             use overload (
31             '""' => 'as_string',
32 234     234   539 bool => sub{1},
33 3         28 fallback => 1,
34 3     3   2235 );
  3         9673  
35 3     3   332 use Scalar::Util ();
  3         5  
  3         75  
36 3     3   1987 use Wanted;
  3         7722  
  3         6660  
37             # ""root" is treated as a special unicode_language_subtag"
38             # <https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier>
39             # NOTE: $LOCALE_BCP47_RE
40 3     3   25 our $LOCALE_BCP47_RE = qr/
41             (?:
42             (?:
43             # "root" is treated as a special Unicode language subtag in the LDML and required in the valid pattern
44             (?<root>root)
45             |
46             (?<language>[a-z]{2})
47             |
48             (?<language3>[a-z]{3})
49             )
50             # "Up to three optional extended language subtags composed of three letters each, separated by hyphens"
51             # "There is currently no extended language subtag registered in the Language Subtag Registry without an equivalent and preferred primary language subtag"
52             (?:
53             \-
54             (?<extended>
55             [a-z]{3}
56             (?:\-[a-z]{3}){0,2}
57             )
58             )?
59             )
60             # ISO 15924 for scripts
61             (?:
62             -
63             (?:
64             (?<script>[A-Z][a-z]{3})
65             |
66             (?<script>[a-z]{4})
67             )
68             )?
69             (?:
70             (?:
71             -
72             (?<territory>
73             (?<country_code>[A-Z]{2})
74             |
75             # BCP47, section 2.2.4.4: the UN Standard Country or Area Codes for Statistical Use
76             # We are careful not to catch a following variant starting with a digit.
77             (?<region>\d{3}(?!\d))
78             )
79             )?
80             # "Optional variant subtags, separated by hyphens, each composed of five to eight letters, or of four characters starting with a digit"
81             # ca-ES-valencia
82             # country code can be skipped if the variant is limited to a country
83             # be-tarask
84             (?:
85             -
86             (?<variant>
87             (?:
88             (?:[[:alnum:]]{5,8})
89             |
90             (?:\d[[:alnum:]]{3})
91             )
92             (?:
93             \-
94             (?:
95             (?:[[:alnum:]]{5,8})
96             |
97             (?:\d[[:alnum:]]{3})
98             )
99             )*
100             )
101             )?
102             )?
103             /xi;
104             # We need the same regular express as $LOCALE_BCP47_RE, but without named capturing group
105             # so it does not interfere with matches from $LOCALE_BCP47_RE
106             # NOTE: $LOCALE_BCP47_NAMELESS_RE
107 3         9 our $LOCALE_BCP47_NAMELESS_RE = qr/
108             (?:
109             (?:
110             # "root" is treated as a special Unicode language subtag in the LDML and required in the valid pattern
111             (?:root)
112             |
113             (?:[a-z]{2})
114             |
115             (?:[a-z]{3})
116             )
117             # "Up to three optional extended language subtags composed of three letters each, separated by hyphens"
118             # "There is currently no extended language subtag registered in the Language Subtag Registry without an equivalent and preferred primary language subtag"
119             (?:
120             \-
121             (?:
122             [a-z]{3}
123             (?:\-[a-z]{3}){0,2}
124             )
125             )?
126             )
127             # ISO 15924 for scripts
128             (?:
129             -
130             (?:
131             (?:[A-Z][a-z]{3})
132             |
133             (?:[a-z]{4})
134             )
135             )?
136             (?:
137             (?:
138             -
139             (?:
140             (?:[A-Z]{2})
141             |
142             # BCP47, section 2.2.4.4: the UN Standard Country or Area Codes for Statistical Use
143             # We are careful not to catch a following variant starting with a digit.
144             (?:\d{3}\d{3}(?!\d))
145             )
146             )?
147             # "Optional variant subtags, separated by hyphens, each composed of five to eight letters, or of four characters starting with a digit"
148             # ca-ES-valencia
149             # country code can be skipped if the variant is limited to a country
150             # be-tarask
151             (?:
152             -
153             (?:
154             (?:
155             (?:[[:alnum:]]{5,8})
156             |
157             (?:\d[[:alnum:]]{3})
158             )
159             (?:
160             \-
161             (?:
162             (?:[[:alnum:]]{5,8})
163             |
164             (?:\d[[:alnum:]]{3})
165             )
166             )*
167             )
168             )?
169             )?
170             /xi;
171             # NOTE: $LOCALE_UNICODE_SUBTAG_RE
172 3         8 our $LOCALE_UNICODE_SUBTAG_RE = qr/
173             (?<ext_unicode_subtag>
174             (?:
175             (?<ext_calendar>ca)
176             |
177             (?<ext_currency_format>cf)
178             |
179             (?<ext_collation>co)
180             |
181             (?<ext_currency>cu)
182             |
183             (?<ext_dict_break_exclusion>dx)
184             |
185             (?<ext_emoji>em)
186             |
187             (?<ext_first_day>fw)
188             |
189             (?<ext_hour_cycle>hc)
190             |
191             (?<ext_line_break>lb)
192             |
193             (?<ext_line_break_word>lw)
194             |
195             (?<ext_measurement>ms)
196             |
197             (?<ext_unit>mu)
198             |
199             (?<ext_number>nu)
200             |
201             (?<ext_region_override>rg)
202             |
203             (?<ext_subdivision>sd)
204             |
205             (?<ext_sentence_break_suppression>ss)
206             |
207             (?<ext_time_zone>tz)
208             |
209             (?<ext_variant>va)
210             |
211             (?<ext_unicode_unknown>
212             [a-zA-Z0-9]{2,8}
213             )
214             )
215             (?<ext_unicode_values>
216             (?:\-
217             # Collation or Transformation subtags, eventhough the latter should not be here
218             (?!(?:ka|kb|kc|kf|kh|kk|kn|kr|ks|kv|vt|d0|h0|i0|k0|m0|s0|t0|x0|[a]0)[^[:alnum:]])
219             [a-zA-Z0-9]{2,8}
220             )*
221             )
222             )
223             (?:
224             \-
225             (?:
226             # Should not be here, but could be malformed
227             (?<transform_options>
228             (?:d0|h0|i0|k0|m0|s0|t0|x0|[a]0)
229             (?:\-[a-zA-Z0-9]{2,8})*
230             )
231             |
232             (?<collation_options>
233             (?:ka|kb|kc|kf|kh|kk|kn|kr|ks|kv|vt)
234             (?:\-[a-zA-Z0-9]{2,8})*
235             )
236             )
237             )?
238             /xi;
239             # NOTE: $LOCALE_TRANSFORM_PARAMETERS_RE
240 3         9 our $LOCALE_TRANSFORM_PARAMETERS_RE = qr/(?:d0|h0|i0|k0|m0|s0|t0|x0|[a]0)/i;
241             # NOTE: $LOCALE_TRANSFORM_SUBTAG_RE
242 3         2358 our $LOCALE_TRANSFORM_SUBTAG_RE = qr/
243             (?<ext_transform_locale>
244             $LOCALE_BCP47_NAMELESS_RE
245             )
246             (?:
247             \-
248             (?<ext_transform_subtag>
249             (?:
250             (?<ext_destination>d0)
251             |
252             (?<ext_hybrid>h0)
253             |
254             (?<ext_input>i0)
255             |
256             (?<ext_keyboard>k0)
257             |
258             (?<ext_mechanism>m0)
259             |
260             (?<ext_source>s0)
261             |
262             (?<ext_translation>t0)
263             |
264             (?<ext_private_transform>x0)
265             |
266             (?<ext_transform_unknown>
267             [a-zA-Z0-9]{2,8}
268             )
269             )
270             (?<ext_transform_values>
271             (?:\-
272             # Transformation or Unicode collation subtags, eventhough the latter should not be here
273             (?!(?:ka|kb|kc|kf|kh|kk|kn|kr|ks|kv|vt|d0|h0|i0|k0|m0|s0|t0|x0|[a]0)[^[:alnum:]])
274             [a-zA-Z0-9]{2,8}
275             )*
276             )
277             )
278             )?
279             (?:
280             \-
281             (?:
282             (?<transform_options>
283             (?:d0|h0|i0|k0|m0|s0|t0|x0|[a]0)
284             (?:\-[a-zA-Z0-9]{2,8})*
285             )
286             |
287             # Should not be here, but could be malformed
288             (?<collation_options>
289             (?:ka|kb|kc|kf|kh|kk|kn|kr|ks|kv|vt)
290             (?:\-[a-zA-Z0-9]{2,8})*
291             )
292             )
293             )?
294             /xi;
295             # NOTE: $LOCALE_EXTENSIONS_RE
296 3         3627 our $LOCALE_EXTENSIONS_RE = qr/
297             (?:
298             (?<ext_transform>
299             t
300             \-
301             $LOCALE_TRANSFORM_SUBTAG_RE
302             )
303             |
304             (?<ext_unicode>
305             u
306             \-
307             $LOCALE_UNICODE_SUBTAG_RE
308             )
309             |
310             (?<extension>
311             (?<singleton>[a-wy-z])
312             \-
313             (?<subtag>
314             [a-zA-Z0-9]{2,8}
315             (?:\-[a-zA-Z0-9]{2,8})*
316             )
317             )
318             )
319             /xi;
320             # NOTE: $GRANDFATHERED_IRREGULAR
321 3         3082 our $GRANDFATHERED_IRREGULAR = qr/
322             (?:
323             en-GB-oed
324             |
325             (?:i-
326             (?:ami|bnn|default|enochian|hak|klingon|lux|mingo|navajo|pwn|tao|tay|tsu)
327             )
328             |
329             (?:sgn-(?:BE-FR|BE-NL|CH-DE))
330             )
331             /xi;
332             # NOTE: $GRANDFATHERED_REGULAR
333 3         12 our $GRANDFATHERED_REGULAR = qr/
334             (?:
335             art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang
336             )
337             /xi;
338             # Possible IETF BCP 47 language tags:
339             # fr
340             # fre
341             # fr-Bret
342             # fr-FR
343             # fr-Bret-FR
344             # See: <https://en.wikipedia.org/wiki/IETF_language_tag#Syntax_of_language_tags>
345             # <https://en.wikipedia.org/wiki/ISO_15924>
346             # Grandfathered subtags: <https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.8>
347             # NOTE: $LOCALE_RE
348 3         8859 our $LOCALE_RE = qr/
349             (?<locale_bcp47>
350             (?:
351             (?:
352             x
353             \-
354             (?<privateuse>
355             [a-zA-Z0-9]{1,8}
356             (?:\-[a-zA-Z0-9]{1,8})*
357             )
358             )
359             |
360             (?<grandfathered>
361             (?<grandfathered_irregular>$GRANDFATHERED_IRREGULAR)
362             |
363             (?<grandfathered_regular>$GRANDFATHERED_REGULAR)
364             )
365             |
366             $LOCALE_BCP47_RE
367             )
368             )
369             # BCP47, section 2.2.6:
370             # "Optional extension subtags, separated by hyphens, each composed of a single character, with the exception of the letter x, and a hyphen followed by one or more subtags of two to eight characters each, separated by hyphens"
371             (?:
372             \-
373             (?:
374             (?:
375             (?<locale_extensions>
376             $LOCALE_EXTENSIONS_RE
377             (?:
378             \-
379             $LOCALE_EXTENSIONS_RE
380             )*
381             )?
382             # "An optional private-use subtag, composed of the letter x and a hyphen followed by subtags of one to eight characters each, separated by hyphens"
383             (?:
384             \-
385             (?<private_extension>
386             x
387             \-
388             (?<private_subtag>
389             [a-zA-Z0-9]{1,8}
390             (?:\-[a-zA-Z0-9]{1,8})*
391             )
392             )
393             )*
394             )
395             |
396             (?<private_extension>
397             x
398             \-
399             (?<private_subtag>
400             [a-zA-Z0-9]{1,8}
401             (?:\-[a-zA-Z0-9]{1,8})*
402             )
403             )
404             )
405             )?
406             /xi;
407 3         63 our $PROP_TO_SUB = {};
408             # False, by default
409 3         8 our $EXPLICIT_BOOLEAN = 0;
410 3         237 our $VERSION = 'v0.4.0';
411             };
412              
413 3     3   26 use strict;
  3         5  
  3         87  
414 3     3   14 use warnings;
  3         6  
  3         31619  
415              
416             sub new
417             {
418 89     89 1 1292284 my $this = shift( @_ );
419 89   66     548 my $self = bless( {} => ( ref( $this ) || $this ) );
420 89   50     326 my $locale = shift( @_ ) ||
421             return( $self->error( "No locale was provided." ) );
422             # u-dx
423 89         320 $self->{break_exclusion} = undef;
424             # u-ca
425 89         219 $self->{calendar} = undef;
426             # u-co
427 89         197 $self->{collation} = undef;
428             # ISO3166 2-letters country code
429 89         162 $self->{country_code} = undef;
430             # u-cf
431 89         216 $self->{cu_format} = undef;
432             # u-cu
433 89         278 $self->{currency} = undef;
434             # t-d0
435 89         162 $self->{destination} = undef;
436             # u-em
437 89         170 $self->{emoji} = undef;
438 89         176 $self->{extended} = undef;
439 89   50     422 $self->{fatal} = ( $FATAL_EXCEPTIONS // 0 );
440             # u-fw
441 89         278 $self->{first_day} = undef;
442 89         194 $self->{grandfathered_irregular} = undef;
443 89         173 $self->{grandfathered_regular} = undef;
444             # u-hc
445 89         164 $self->{hour_cycle} = undef;
446             # t-h0
447 89         173 $self->{hybrid} = undef;
448             # t-i0
449 89         153 $self->{input} = undef;
450 89         163 $self->{language} = undef;
451 89         223 $self->{language3} = undef;
452             # u-lb
453 89         155 $self->{line_break} = undef;
454             # u-lw
455 89         148 $self->{line_break_word} = undef;
456             # u-ms
457 89         195 $self->{measurement} = undef;
458             # u-nu
459 89         301 $self->{number} = undef;
460             # Overlong country code (3-characters code) whereas it should be 2-characters code
461             # For example: PAN -> PA
462             # See the 'alias' method in Locale::Unicode::Data to convert those overlong territory to their 2-characters equivalent
463 89         173 $self->{overlong} = undef;
464             # u-mu
465 89         167 $self->{unit} = undef;
466             # t-m0
467 89         207 $self->{mechanism} = undef;
468             # x-something
469 89         160 $self->{private} = undef;
470 89         145 $self->{privateuse} = undef;
471 89         158 $self->{region} = undef;
472             # u-rg
473 89         179 $self->{region_override} = undef;
474             # t-s0
475 89         211 $self->{source} = undef;
476 89         239 $self->{script} = undef;
477 89         175 $self->{territory} = undef;
478             # t-t0
479 89         165 $self->{translation} = undef;
480             # u-sd
481 89         203 $self->{subdivision} = undef;
482             # t-x
483 89         165 $self->{t_private} = undef;
484             # u-tz
485 89         168 $self->{time_zone} = undef;
486             # u-va
487 89         175 $self->{variant} = undef;
488             # A simple dictionary that stores the preferred boolean representation for each attribute
489             # i.e. yes or true, no or false
490             # literal or logic
491 89         183 $self->{_bool_types} = {};
492 89         204 my @args = @_;
493 89 50 33     500 if( scalar( @args ) == 1 &&
    50 33        
494             defined( $args[0] ) &&
495             ref( $args[0] ) eq 'HASH' )
496             {
497 0         0 my $opts = shift( @args );
498             # We need to set up early, so we can use it soon after
499 0 0       0 $self->{fatal} = delete( $opts->{fatal} ) if( exists( $opts->{fatal} ) );
500 0         0 @args = %$opts;
501             }
502             elsif( ( scalar( @args ) % 2 ) )
503             {
504 0         0 return( $self->error( sprintf( "Uneven number of parameters provided (%d). Should receive key => value pairs. Parameters provided are: %s", scalar( @args ), join( ', ', @args ) ) ) );
505             }
506              
507 89         346 for( my $i = 0; $i < scalar( @args ); $i += 2 )
508             {
509 2 100       28 if( $args[$i] eq 'fatal' )
510             {
511 1         5 $self->{fatal} = $args[$i + 1];
512 1         8 last;
513             }
514             }
515              
516             # If the locale provided contains any subtags, parse it
517 89 100 66     388 if( index( $locale, '-' ) != -1 ||
518             index( $locale, '_' ) != -1 )
519             {
520 73         153 $locale =~ tr/_/-/;
521             }
522 89   50     327 my $ref = $self->parse( $locale ) ||
523             return( $self->pass_error );
524 89 100       279 return( $self->error( "Invalid locale value \"${locale}\" provided." ) ) if( !scalar( keys( %$ref ) ) );
525 88 50       300 $self->apply( $ref ) || return( $self->pass_error );
526              
527             # Then, if the user provided with an hash or hash reference of options, we apply them
528 88         369 for( my $i = 0; $i < scalar( @args ); $i++ )
529             {
530 1         4 my $name = $args[ $i ];
531 1         3 my $val = $args[ ++$i ];
532 1         5 my $meth = $self->can( $name );
533 1 50       6 if( !defined( $meth ) )
    50          
534             {
535 0         0 return( $self->error( "Unknown method \"${meth}\" provided for locale \"${locale}\"." ) );
536             }
537             elsif( !defined( $meth->( $self, $val ) ) )
538             {
539 0 0 0     0 if( defined( $val ) && $self->error )
540             {
541 0         0 return( $self->pass_error );
542             }
543             }
544             }
545 88         512 return( $self );
546             }
547              
548             sub apply
549             {
550 88     88 1 170 my $self = shift( @_ );
551 88         253 my $hash = $self->_get_args_as_hash( @_ );
552 88 50       222 return( $self ) if( !scalar( keys( %$hash ) ) );
553 88         270 foreach my $prop ( keys( %$hash ) )
554             {
555 186 100 100     761 next if( $prop eq 'transform_ext' || $prop eq 'unicode_ext' );
556 172         260 my $code;
557 172 100       558 unless( $code = $PROP_TO_SUB->{ $prop } )
558             {
559 12         55 $code = $self->can( $prop );
560 12 50       31 if( !$code )
561             {
562 0 0 0     0 warn( "No method \"${prop}\" supported in ", ( ref( $self ) || $self ) ) if( warnings::enabled() );
563 0         0 next;
564             }
565 12         33 $PROP_TO_SUB->{ $prop } = $code;
566             }
567 172         472 $code->( $self, $hash->{ $prop } );
568             }
569 88         414 return( $self );
570             }
571              
572             sub as_string
573             {
574 83     83 1 12168 my $self = shift( @_ );
575 83 100 50     510 return( $self->{_cache_value} ) if( $self->{_cache_value} && !CORE::length( $self->{_reset} // '' ) );
      66        
576 48         798 my $unicodes =
577             {
578             ca => 'calendar',
579             cf => 'cu_format',
580             co => 'collation',
581             cu => 'currency',
582             dx => 'break_exclusion',
583             em => 'emoji',
584             fw => 'first_day',
585             hc => 'hour_cycle',
586             lb => 'line_break',
587             lw => 'line_break_word',
588             ms => 'measurement',
589             mu => 'unit',
590             nu => 'number',
591             rg => 'region_override',
592             sd => 'subdivision',
593             ss => 'sentence_break',
594             tz => 'time_zone',
595             va => 'va',
596             };
597 48         810 my $collation =
598             {
599             ka => 'colAlternate',
600             kb => { type => 'boolean', method => 'colBackwards' },
601             kc => { type => 'boolean', method => 'colCaseLevel' },
602             kf => 'colCaseFirst',
603             kh => { type => 'boolean', method => 'colHiraganaQuaternary' },
604             kk => { type => 'boolean', method => 'colNormalization' },
605             kn => { type => 'boolean', method => 'colNumeric' },
606             kr => 'colReorder',
607             ks => 'colStrength',
608             kv => 'colValue',
609             vt => 'colVariableTop',
610             };
611 48         379 my $transform =
612             {
613             d0 => 'destination',
614             h0 => 'hybrid',
615             i0 => 'input',
616             k0 => 'keyboard',
617             m0 => 'mechanism',
618             s0 => 'source',
619             t0 => 'translation',
620             x0 => 't_private',
621             };
622 48         724 my $others =
623             {
624             x_ => 'private',
625             };
626 48         320 my $map =
627             [
628             unicode => { prefix => 'u', data => $unicodes },
629             # und-u-ka-noignore
630             collation => { prefix => 'u', data => $collation },
631             transform => { prefix => 't', data => $transform },
632             ];
633 48         100 my $result = {};
634 48         162 for( my $i = 0; $i < scalar( @$map ); $i += 2 )
635             {
636 144         271 my $type = $map->[$i];
637 144         297 my $dict = $map->[$i + 1];
638 144         274 my $prefix = $dict->{prefix};
639 144         203 my $ref = $dict->{data};
640 144         1356 foreach my $tag ( sort( keys( %$ref ) ) )
641             {
642 1776         2695 my $meth;
643 1776         2396 my $def = {};
644 1776 100       13211 if( ref( $ref->{ $tag } ) eq 'HASH' )
645             {
646 240         441 $def = $ref->{ $tag };
647 240         449 $meth = $def->{method};
648             }
649             else
650             {
651 1536         2443 $meth = $ref->{ $tag };
652             }
653 1776         2282 my $code;
654 1776 100       4264 unless( $code = $PROP_TO_SUB->{ $tag } )
655             {
656 36   50     162 $code = $self->can( $meth ) || die( "Unknown method '${meth}' for ${type} subtag '${tag}'" );
657 36         76 $PROP_TO_SUB->{ $tag } = $code;
658             }
659              
660 1776         3936 my $val = $code->( $self );
661 1776 100       6895 next if( !defined( $val ) );
662 17 100       92 $result->{ $prefix } = [] if( !exists( $result->{ $prefix } ) );
663 17 50 33     64 if( exists( $def->{type} ) && $def->{type} eq 'boolean' )
664             {
665             # We are explicit about the true value, but it could be ignored and be implicit.
666             # push( @{$result->{ $prefix }}, join( '-', $tag, ( $val ? 'true' : 'false' ) ) );
667 0 0       0 push( @{$result->{ $prefix }}, ( $EXPLICIT_BOOLEAN ? join( '-', $tag, ( $val ? 'true' : 'false' ) ) : ( $val ? $tag : join( '-', $tag, 'false' ) ) ) );
  0 0       0  
    0          
668             }
669             else
670             {
671 17         24 push( @{$result->{ $prefix }}, join( '-', $tag, $val ) );
  17         108  
672             }
673             }
674             }
675 48         96 my @parts = ();
676              
677 48         182 push( @parts, $self->core );
678              
679 48 100 33     151 if( my $transform_locale = $self->transform_locale )
    50 50        
680             {
681 9         18 unshift( @{$result->{t}}, $transform_locale );
  9         43  
682             }
683             # There is no transformation locale and yet the user has set some transformation subtags.
684             # We warn the user about it.
685             elsif( exists( $result->{t} ) &&
686             ref( $result->{t} ) eq 'ARRAY' &&
687 0         0 scalar( @{$result->{t}} ) )
688             {
689 0 0       0 warn( "You are attempting at setting ", scalar( @{$result->{t}} ), " transform subtags without declaring a transformation locale." ) if( warnings::enabled() );
  0         0  
690             }
691              
692 48         168 foreach my $pref ( qw( u t ) )
693             {
694 96 100       320 if( exists( $result->{ $pref } ) )
695             {
696 13         30 push( @parts, join( '-', $pref, join( '-', @{$result->{ $pref }} ) ) );
  13         57  
697             }
698             }
699 48 100       152 if( my $private = $self->private )
700             {
701 2         7 push( @parts, "x-${private}" );
702             }
703 48         157 my $rv = join( '-', @parts );
704 48         142 $self->{_cache_value} = $rv;
705 48         111 CORE::delete( $self->{_reset} );
706 48         1236 return( $rv );
707             }
708              
709             sub base
710             {
711 6     6 1 29 my $self = shift( @_ );
712 6 100       20 if( @_ )
713             {
714 2         5 my $base = shift( @_ );
715 2 50 33     9 unless( Scalar::Util::blessed( $base ) &&
716             $base->isa( 'Locale::Unicode' ) )
717             {
718 2   50     9 $base = Locale::Unicode->new( "$base" ) ||
719             return( $self->pass_error );
720             }
721             # $base = $base->canonical;
722 2 50       10 if( my $lang = $base->language_id )
723             {
724 2         8 $self->language_id( $lang );
725             }
726             else
727             {
728 0         0 $self->language_id( undef );
729             }
730              
731 2 50       10 if( my $script = $base->script )
732             {
733 0         0 $self->script( $script );
734             }
735             else
736             {
737 2         10 $self->script( undef );
738             }
739              
740 2 50       8 if( my $territory = $base->territory )
741             {
742 2 50       7 $self->territory( $territory ) ||
743             return( $self->pass_error );
744             }
745             else
746             {
747 0         0 $self->territory( undef );
748             }
749              
750 2         5 my $ref;
751 2 100 50     8 if( ( $ref = $base->variants ) &&
      33        
      50        
752             ref( $ref // '' ) eq 'ARRAY' &&
753             scalar( @$ref ) )
754             {
755 1         4 local $" = '-';
756 1         7 $self->variant( "@$ref" );
757             }
758             else
759             {
760 1         5 $self->variant( undef );
761             }
762             }
763 6         22 return( $self->core );
764             }
765              
766             # u-dx
767 48     48 1 125 sub break_exclusion { return( shift->reset(@_)->_set_get_prop( 'break_exclusion', @_ ) ); }
768              
769             # u-ca
770 4     4 1 122 sub ca { return( shift->calendar( @_ ) ); }
771              
772 54     54 1 193 sub calendar { return( shift->reset(@_)->_set_get_prop( 'calendar', @_ ) ); }
773              
774             # NOTE: canonical -> specs <https://unicode.org/reports/tr35/tr35.html#Canonical_Unicode_Locale_Identifiers>
775             # <https://unicode.org/reports/tr35/tr35.html#LocaleId_Canonicalization>
776             # <https://unicode.org/reports/tr35/tr35.html#5.-canonicalizing-syntax>
777             sub canonical
778             {
779 3     3 1 1938 my $self = shift( @_ );
780 3         7 local $EXPLICIT_BOOLEAN = 0;
781 3         13 my $clone = Locale::Unicode->new( "$self" );
782 3 50       15 if( my $privateuse = $clone->privateuse )
    50          
783             {
784 0         0 return( $clone );
785             }
786             elsif( my $grandfathered = $clone->grandfathered )
787             {
788 0         0 return( $clone );
789             }
790              
791 3 100       25 if( my $variant = $self->variant )
792             {
793             # Make sure we have unique variants
794             # "The sequence of variant subtags must not have any duplicates (eg, de-1996-fonipa-1996 is not syntactically well-formed)."
795             # <https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier>
796             my $uniq = sub
797             {
798 1     1   2 my %seen;
799 1         12 grep( !$seen{ $_ }++, @_ );
800 1         28 };
801 1         13 my $variant2 = join( '-', $uniq->( sort( map( lc( $_ ), split( /-/, $variant ) ) ) ) );
802 1 50       9 $clone->variant( $variant2 ) if( $variant2 ne $variant );
803             }
804              
805             # We query the country_code method only, because territory includes both world region
806             # and country code, and world region is only digits that do not need to be in uppercase
807 3 100       10 if( my $country_code = $self->country_code )
808             {
809 1         4 my $cc = uc( $country_code );
810 1 50       6 $clone->country_code( $cc ) if( $cc ne $country_code );
811             }
812              
813 3 100       25 if( my $script = $self->script )
814             {
815 1         4 my $script2 = ucfirst( lc( $script ) );
816 1 50       7 $clone->script( $script2 ) if( $script2 ne $script );
817             }
818              
819 3         10 my( $lang, $lang3 );
820 3 50 33     10 if( ( $lang = $self->language ) ||
821             ( $lang3 = $self->language3 ) )
822             {
823             # <https://unicode.org/reports/tr35/tr35.html#Unicode_Locale_Identifier_BCP_47_to_CLDR>
824             # "the primary language subtag "und" is replaced with "root" if no script, region, or variant subtags are present."
825             # Hmmm, I am really reluctant to do this, because other parts of the LDML indicates we should stick with dash and use 'und' and 'root' is not compliant with RFC standard that a language ID should be 2 to 3-characters
826             # if( !$locale->script &&
827             # !$locale->territory &&
828             # !$locale->variant )
829             # {
830             # $locale->language( 'root' );
831             # }
832 3 50       11 if( $lang )
    0          
833             {
834 3         9 my $lang_canon = lc( $lang );
835 3 100       100 if( $lang_canon eq 'root' )
    50          
836             {
837 1         6 $clone->language3( 'und' );
838             }
839             elsif( $lang_canon ne $lang )
840             {
841 0         0 $clone->language( $lang_canon );
842             }
843             }
844             elsif( $lang3 )
845             {
846 0         0 my $lang_canon = lc( $lang3 );
847 0 0       0 $clone->language3( $lang_canon ) if( $lang_canon ne $lang3 );
848             }
849             }
850             else
851             {
852 0         0 $clone->language( 'und' );
853             }
854 3         21 return( $clone );
855             }
856              
857             # u-cf
858 0     0 1 0 sub cf { return( shift->cu_format( @_ ) ); }
859              
860             sub clone
861             {
862 0     0 1 0 my $self = shift( @_ );
863 0   0     0 my $new = $self->new( "$self" ) || return( $self->pass_error );
864 0         0 return( $new );
865             }
866              
867             # u-co
868 1     1 1 5 sub co { return( shift->collation( @_ ) ); }
869              
870             # u-ka
871 50     50 1 171 sub colAlternate { return( shift->reset(@_)->_set_get_prop({
872             field => 'col_alternate',
873             regexp => qr/[[:alnum:]][[:alnum:]\-]+/,
874             }, @_ ) ); }
875              
876             # u-kb
877 48     48 1 144 sub colBackwards { return( shift->reset(@_)->_set_get_prop({
878             field => 'col_backwards',
879             type => 'boolean',
880             }, @_ ) ); }
881              
882             # u-kc
883 48     48 1 171 sub colCaseLevel { return( shift->reset(@_)->_set_get_prop({
884             field => 'col_case_level',
885             type => 'boolean',
886             }, @_ ) ); }
887              
888             # u-kf
889 52     52 1 1434 sub colCaseFirst { return( shift->reset(@_)->_set_get_prop({
890             field => 'col_case_first',
891             # lower, upper, undef
892             regexp => qr/[[:alnum:]]+/,
893             }, @_ ) ); }
894              
895             # u-co
896 50     50 1 150 sub collation { return( shift->reset(@_)->_set_get_prop({
897             field => 'collation',
898             regexp => qr/[[:alnum:]]+/,
899             }, @_ ) ); }
900              
901             # u-kh
902 48     48 1 171 sub colHiraganaQuaternary { return( shift->reset(@_)->_set_get_prop({
903             field => 'col_hiragana_quaternary',
904             type => 'boolean',
905             }, @_ ) ); }
906              
907 0     0 1 0 sub colNormalisation { return( shift->colNormalization( @_ ) ); }
908              
909             # u-kk
910 48     48 1 154 sub colNormalization { return( shift->reset(@_)->_set_get_prop({
911             field => 'col_normalisation',
912             type => 'boolean',
913             }, @_ ) ); }
914              
915             # u-kn
916 48     48 1 143 sub colNumeric { return( shift->reset(@_)->_set_get_prop({
917             field => 'col_numeric',
918             type => 'boolean',
919             }, @_ ) ); }
920              
921             # u-kr
922 48     48 1 174 sub colReorder { return( shift->reset(@_)->_set_get_prop({
923             field => 'col_reorder',
924             regexp => qr/[[:alnum:]][[:alnum:]\-]+/,
925             }, @_ ) ); }
926              
927             # u-ks
928 48     48 1 139 sub colStrength { return( shift->reset(@_)->_set_get_prop({
929             field => 'col_strength',
930             regexp => qr/[[:alnum:]][[:alnum:]\-]+/,
931             }, @_ ) ); }
932              
933             # u-kv
934 48     48 1 175 sub colValue { return( shift->reset(@_)->_set_get_prop({
935             field => 'col_value',
936             regexp => qr/[[:alnum:]]+/,
937             }, @_ ) ); }
938              
939             # u-vt
940 48     48 1 133 sub colVariableTop { return( shift->reset(@_)->_set_get_prop({
941             field => 'col_variable_top',
942             regexp => qr/[[:alnum:]]+/,
943             }, @_ ) ); }
944              
945             sub core
946             {
947 61     61 1 113 my $self = shift( @_ );
948 61         103 my @locale_parts = ();
949 61 100       173 if( my $privateuse = $self->privateuse )
    100          
950             {
951 1         5 push( @locale_parts, 'x-' . $privateuse );
952             }
953             elsif( my $grandfathered = $self->grandfathered )
954             {
955 2         6 push( @locale_parts, $grandfathered );
956             }
957             else
958             {
959 58 100       160 if( my $lang = $self->language )
    50          
960             {
961 48         125 push( @locale_parts, $lang );
962             }
963             elsif( my $lang3 = $self->language3 )
964             {
965 10         21 push( @locale_parts, $lang3 );
966             }
967             # 'und' for 'undefined'
968             else
969             {
970 0         0 push( @locale_parts, 'und' );
971             }
972              
973 58 100       195 if( my $extended = $self->extended )
974             {
975 4         11 push( @locale_parts, $extended );
976             }
977              
978 58 100       178 if( my $script = $self->script )
979             {
980 15         33 push( @locale_parts, $script );
981             }
982              
983 58 100       154 if( my $cc = $self->country_code )
    50          
984             {
985 26         66 push( @locale_parts, $cc );
986             }
987             elsif( my $region = $self->region )
988             {
989 0         0 push( @locale_parts, $region );
990             }
991              
992 58 100       434 if( my $variant = $self->variant )
993             {
994 10         26 push( @locale_parts, $variant );
995             }
996             }
997 61         631 return( join( '-', @locale_parts ) );
998             }
999              
1000             sub country_code { return( shift->reset(@_)->_set_get_prop({
1001             field => 'country_code',
1002             on_update => sub
1003             {
1004 29     29   65 $_[0]->{region} = undef;
1005 29         56 $_[0]->{overlong} = undef;
1006             },
1007 106     106 1 3207 }, @_ ) ); }
1008              
1009             # u-cf
1010 48     48 1 138 sub cu_format { return( shift->reset(@_)->_set_get_prop( 'cu_format', @_ ) ); }
1011              
1012             # u-cu
1013 0     0 1 0 sub cu { return( shift->reset(@_)->_set_get_prop( 'currency', @_ ) ); }
1014              
1015             # u-cu
1016 48     48 1 139 sub currency { return( shift->reset(@_)->_set_get_prop( 'currency', @_ ) ); }
1017              
1018             # t-d0
1019 0     0 1 0 sub d0 { return( shift->reset(@_)->_set_get_prop( 'destination', @_ ) ); }
1020              
1021             # t-d0
1022 0     0 1 0 sub dest { return( shift->reset(@_)->_set_get_prop( 'destination', @_ ) ); }
1023              
1024             # t-d0
1025 48     48 1 142 sub destination { return( shift->reset(@_)->_set_get_prop( 'destination', @_ ) ); }
1026              
1027             # u-dx
1028 0     0 1 0 sub dx { return( shift->reset(@_)->_set_get_prop( 'break_exclusion', @_ ) ); }
1029              
1030             # u-em
1031 0     0 1 0 sub em { return( shift->reset(@_)->_set_get_prop( 'emoji', @_ ) ); }
1032              
1033             # u-em
1034 48     48 1 144 sub emoji { return( shift->reset(@_)->_set_get_prop( 'emoji', @_ ) ); }
1035              
1036             sub error
1037             {
1038 1     1 1 3 my $self = shift( @_ );
1039 1 50       4 if( @_ )
1040             {
1041 1 50       7 my $msg = join( '', map( ( ref( $_ ) eq 'CODE' ) ? $_->() : $_, @_ ) );
1042 1         14 $self->{error} = $ERROR = Locale::Unicode::Exception->new({
1043             skip_frames => 1,
1044             message => $msg,
1045             });
1046 1 50       7 if( $self->fatal )
1047             {
1048 1         17 die( $self->{error} );
1049             }
1050             else
1051             {
1052 0 0       0 warn( $msg ) if( warnings::enabled() );
1053 0 0       0 rreturn( Locale::Unicode::NullObject->new ) if( want( 'OBJECT' ) );
1054 0         0 return;
1055             }
1056             }
1057 0 0       0 return( ref( $self ) ? $self->{error} : $ERROR );
1058             }
1059              
1060 74     74 1 6096 sub extended { return( shift->reset(@_)->_set_get_prop( 'extended', @_ ) ); }
1061              
1062 0     0 1 0 sub false { return( $Locale::Unicode::Boolean::false ); }
1063              
1064 3     3 1 16 sub fatal { return( shift->_set_get_prop( 'fatal', @_ ) ); }
1065              
1066             # u-fw
1067 48     48 1 163 sub first_day { return( shift->reset(@_)->_set_get_prop( 'first_day', @_ ) ); }
1068              
1069             # u-fw
1070 0     0 1 0 sub fw { return( shift->reset(@_)->_set_get_prop( 'first_day', @_ ) ); }
1071              
1072             sub grandfathered
1073             {
1074 65     65 1 1420 my $self = shift( @_ );
1075 65 100       141 if( @_ )
1076             {
1077 2         6 my $val = shift( @_ );
1078 2         9 $self->reset(1);
1079 2 50       298 if( !defined( $val ) )
    100          
    50          
1080             {
1081 0         0 $self->_set_get_prop( 'grandfathered_irregular', undef );
1082 0         0 $self->_set_get_prop( 'grandfathered_regular', undef );
1083             }
1084             elsif( $val =~ /^$GRANDFATHERED_IRREGULAR$/ )
1085             {
1086 1         6 $self->grandfathered_irregular( $val );
1087             }
1088             elsif( $val =~ /^$GRANDFATHERED_REGULAR$/ )
1089             {
1090 1         7 $self->grandfathered_regular( $val );
1091             }
1092             else
1093             {
1094 0 0       0 warn( "Value provided does not seem to be either a regular or irregular grandfathered language tag." ) if( warnings::enabled() );
1095             }
1096             }
1097 65   100     210 return( $self->_set_get_prop( 'grandfathered_irregular' ) || $self->_set_get_prop( 'grandfathered_regular' ) );
1098             }
1099              
1100             sub grandfathered_irregular { return( shift->reset(@_)->_set_get_prop( {
1101             field => 'grandfathered_irregular',
1102             on_update => sub
1103             {
1104 18     18   64 $_[0]->{language} = undef;
1105 18         63 $_[0]->{language3} = undef;
1106 18         36 $_[0]->{privateuse} = undef;
1107 18         39 $_[0]->{grandfathered_regular} = undef;
1108             },
1109 47     47 1 16687 }, @_ ) ); }
1110              
1111             sub grandfathered_regular { return( shift->reset(@_)->_set_get_prop( {
1112             field => 'grandfathered_regular',
1113             on_update => sub
1114             {
1115 10     10   26 $_[0]->{language} = undef;
1116 10         20 $_[0]->{language3} = undef;
1117 10         17 $_[0]->{privateuse} = undef;
1118 10         21 $_[0]->{grandfathered_irregular} = undef;
1119             },
1120 39     39 1 24957 }, @_ ) ); }
1121              
1122             # t-h0
1123 0     0 1 0 sub h0 { return( shift->reset(@_)->_set_get_prop( 'hybrid', @_ ) ); }
1124              
1125             # u-hc
1126 0     0 1 0 sub hc { return( shift->reset(@_)->_set_get_prop( 'hour_cycle', @_ ) ); }
1127              
1128             # u-hc
1129 48     48 1 199 sub hour_cycle { return( shift->reset(@_)->_set_get_prop( 'hour_cycle', @_ ) ); }
1130              
1131             # t-h0
1132 48     48 1 144 sub hybrid { return( shift->reset(@_)->_set_get_prop( 'hybrid', @_ ) ); }
1133              
1134             # t-i0
1135 0     0 1 0 sub i0 { return( shift->reset(@_)->_set_get_prop( 'input', @_ ) ); }
1136              
1137             # t-i0
1138 48     48 1 192 sub input { return( shift->reset(@_)->_set_get_prop( 'input', @_ ) ); }
1139              
1140             # t-k0
1141 0     0 1 0 sub k0 { return( shift->reset(@_)->_set_get_prop( 'keyboard', @_ ) ); }
1142              
1143             # u-ka
1144 1     1 1 1130 sub ka { return( shift->colAlternate( @_ ) ); }
1145              
1146             # u-kb
1147 0     0 1 0 sub kb { return( shift->colBackwards( @_ ) ); }
1148              
1149             # u-kc
1150 0     0 1 0 sub kc { return( shift->colCaseLevel( @_ ) ); }
1151              
1152             # t-k0
1153 48     48 1 145 sub keyboard { return( shift->reset(@_)->_set_get_prop( 'keyboard', @_ ) ); }
1154              
1155             # u-kf
1156 0     0 1 0 sub kf { return( shift->colCaseFirst( @_ ) ); }
1157              
1158             # u-kh
1159 0     0 1 0 sub kh { return( shift->colHiraganaQuaternary( @_ ) ); }
1160              
1161             # u-kk
1162 0     0 1 0 sub kk { return( shift->colNormalization( @_ ) ); }
1163              
1164             # u-kn
1165 0     0 1 0 sub kn { return( shift->colNumeric( @_ ) ); }
1166              
1167             # u-kr
1168 0     0 1 0 sub kr { return( shift->colReorder( @_ ) ); }
1169              
1170             # u-ks
1171 0     0 1 0 sub ks { return( shift->colStrength( @_ ) ); }
1172              
1173             # u-kv
1174 0     0 1 0 sub kv { return( shift->colValue( @_ ) ); }
1175              
1176             sub lang { return( shift->reset(@_)->_set_get_prop( {
1177             field => 'language',
1178             on_update => sub
1179             {
1180 57     57   124 $_[0]->{language3} = undef;
1181 57         98 $_[0]->{grandfathered_irregular} = undef;
1182 57         105 $_[0]->{grandfathered_regular} = undef;
1183 57         113 $_[0]->{privateuse} = undef;
1184             },
1185 166     166 1 448 }, @_ ) ); }
1186              
1187             sub lang3 { return( shift->reset(@_)->_set_get_prop( {
1188             field => 'language3',
1189             on_update => sub
1190             {
1191 9     9   17 $_[0]->{language} = undef;
1192 9         15 $_[0]->{grandfathered_irregular} = undef;
1193 9         14 $_[0]->{grandfathered_regular} = undef;
1194 9         17 $_[0]->{privateuse} = undef;
1195             },
1196 51     51 1 174 }, @_ ) ); }
1197              
1198 166     166 1 28558 sub language { return( shift->lang( @_ ) ); }
1199              
1200             sub language_extended
1201             {
1202 5     5 1 5373 my $self = shift( @_ );
1203 5         12 my @parts = ();
1204 5 100       15 if( my $lang = $self->language )
    50          
1205             {
1206 4         12 push( @parts, $lang );
1207             }
1208             elsif( my $lang3 = $self->language3 )
1209             {
1210 1         3 push( @parts, $lang3 );
1211             }
1212              
1213 5 100       20 if( my $ext = $self->extended )
1214             {
1215 2         6 push( @parts, $ext );
1216             }
1217 5         28 return( join( '-', @parts ) );
1218             }
1219              
1220 51     51 1 18423 sub language3 { return( shift->lang3( @_ ) ); }
1221              
1222             sub language_id
1223             {
1224 4     4 1 9 my $self = shift( @_ );
1225 4 100       11 if( @_ )
1226             {
1227 2         5 my $val = shift( @_ );
1228 2 50       10 if( !defined( $val ) )
    50          
1229             {
1230 0         0 $self->language( undef );
1231 0         0 $self->language3( undef );
1232             }
1233             elsif( length( $val ) == 3 )
1234             {
1235 0         0 $self->language3( $val );
1236             }
1237             # Should be a 2-characters language ID, but we are not going to enforce it.
1238             # This is the responsibility of the developer.
1239             else
1240             {
1241 2         7 $self->language( $val );
1242             }
1243             }
1244 4   33     21 return( $self->language || $self->language3 );
1245             }
1246              
1247             # u-lb
1248 0     0 1 0 sub lb { return( shift->reset(@_)->_set_get_prop( 'line_break', @_ ) ); }
1249              
1250             # u-lb
1251 48     48 1 132 sub line_break { return( shift->reset(@_)->_set_get_prop( 'line_break', @_ ) ); }
1252              
1253             # u-lw
1254 48     48 1 140 sub line_break_word { return( shift->reset(@_)->_set_get_prop( 'line_break_word', @_ ) ); }
1255              
1256             # NOTE: the term 'locale' is abusive, since a locale is the entire string, and the language is just this part
1257 0     0 1 0 sub locale { return( shift->reset(@_)->_set_get_prop( 'language', @_ ) ); }
1258              
1259 0     0 1 0 sub locale3 { return( shift->reset(@_)->_set_get_prop( 'language3', @_ ) ); }
1260              
1261             # u-lw
1262 0     0 1 0 sub lw { return( shift->reset(@_)->_set_get_prop( 'line_break_word', @_ ) ); }
1263              
1264             # t-m0
1265 1     1 1 1137 sub m0 { return( shift->mechanism( @_ ) ); }
1266              
1267             sub matches
1268             {
1269 1200     1200 1 703443 my $self = shift( @_ );
1270 1200   50     4578 my $lang = shift( @_ ) || return( $self->error( "No language was provided." ) );
1271             # Required by RFC for parsing
1272 1200         9911 $lang =~ tr/_/-/;
1273             # Special language 'root' becomes 'und' for 'undefined'
1274             # if( substr( lc( $lang ), 0, 5 ) eq 'root-' )
1275             # {
1276             # substr( $lang, 0, 4, 'und' );
1277             # }
1278 1200 100       50567 if( $lang =~ /^$LOCALE_RE$/ )
1279             {
1280 1199         44922 my $re = {%+};
1281 1199         8588 return( $re );
1282             }
1283             # Returns false with empty string, but not undef. Undef is reserved for errors
1284 1 50       28 return( wantarray() ? () : '' );
1285             }
1286              
1287             # u-ms
1288 48     48 1 128 sub measurement { return( shift->reset(@_)->_set_get_prop( 'measurement', @_ ) ); }
1289              
1290             # t-m0
1291 50     50 1 147 sub mechanism { return( shift->reset(@_)->_set_get_prop( 'mechanism', @_ ) ); }
1292              
1293             sub merge
1294             {
1295 2     2 1 13 my $self = shift( @_ );
1296 2         6 my @locales = @_;
1297 2 50       8 if( scalar( @_ ) != 1 )
1298             {
1299 0         0 return( $self->error( "I expected 1 locale, but instead received ", scalar( @locales ), " locales." ) );
1300             }
1301 2         4 my $other = shift( @locales );
1302 2 50 33     22 unless( Scalar::Util::blessed( $other ) &&
1303             $other->isa( 'Locale::Unicode' ) )
1304             {
1305 0   0     0 $other = Locale::Unicode->new( "$other" ) ||
1306             return( $self->pass_error( Locale::Unicode->error ) );
1307             }
1308 2 100       20 my @keys = grep{ exists( $PROP_TO_SUB->{ $_ } ) || $self->can( $_ ) } keys( %$self );
  78         305  
1309 2         11 foreach my $prop ( @keys )
1310             {
1311 74 100       181 next if( $prop eq 'variant' );
1312 72 100 66     260 if( exists( $other->{ $prop } ) &&
1313             defined( $other->{ $prop } ) )
1314             {
1315 6         25 $self->$prop( $other->{ $prop } );
1316             }
1317             }
1318 2         4 my $ref;
1319 2 50 50     10 if( ( $ref = $other->variants ) &&
1320             scalar( @$ref ) )
1321             {
1322 2         7 my $orig = $self->variants;
1323 2 100       7 if( scalar( @$orig ) )
1324             {
1325             # Make sure we have unique keys
1326             my $uniq = sub
1327             {
1328 1     1   4 my %seen;
1329 1         10 grep( !$seen{ $_ }++, @_ );
1330 1         7 };
1331 1         4 my @variants = $uniq->( @$orig, @$ref );
1332 1         7 $self->variant( join( '-', @variants ) );
1333             }
1334             else
1335             {
1336 1         4 my $var = $other->variant;
1337 1         4 $self->variant( $var );
1338             }
1339             }
1340 2         20 return( $self );
1341             }
1342              
1343             # u-ms
1344 0     0 1 0 sub ms { return( shift->measurement( @_ ) ); }
1345              
1346             # u-mu
1347 0     0 1 0 sub mu { return( shift->unit( @_ ) ); }
1348              
1349             # u-nu
1350 1     1 1 1174 sub nu { return( shift->number( @_ ) ); }
1351              
1352             # u-nu
1353 50     50 1 189 sub number { return( shift->reset(@_)->_set_get_prop( 'number', @_ ) ); }
1354              
1355             sub overlong { return( shift->reset(@_)->_set_get_prop( {
1356             field => 'overlong',
1357             on_update => sub
1358             {
1359 1     1   3 $_[0]->{country_code} = $_[1];
1360 1         3 $_[0]->{region} = undef;
1361             },
1362 5     5 1 23 }, @_ ) ); }
1363              
1364             sub parse
1365             {
1366 104     104 1 98070 my $self = shift( @_ );
1367 104   50     306 my $this = shift( @_ ) || return( $self->error( "No language string was provided." ) );
1368 104         330 my $opts = $self->_get_args_as_hash( @_ );
1369              
1370 104         255 my $re = $self->matches( $this );
1371 104 50       256 return( $self->pass_error ) if( !defined( $opts ) );
1372              
1373 104         186 my $info = {};
1374             # Value provided failed to match the locale regular expression
1375 104 100       263 return( $info ) if( !$re );
1376             # "root" is treated as a special unicode_language_subtag
1377             # <https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier>
1378 103 50 66     319 if( exists( $re->{root} ) &&
      66        
1379             defined( $re->{root} ) &&
1380             length( $re->{root} ) )
1381             {
1382             $re->{language} = delete( $re->{root} )
1383 4         15 }
1384 103         236 foreach my $prop ( qw( language language3 extended script country_code region variant privateuse grandfathered_irregular grandfathered_regular overlong ) )
1385             {
1386             # the property provided as an option can be undef by design to remove the value
1387 1133 50 66     3975 if( exists( $opts->{ $prop } ) )
    100 66        
1388             {
1389 0         0 $info->{ $prop } = $opts->{ $prop };
1390             }
1391             elsif( exists( $re->{ $prop } ) &&
1392             defined( $re->{ $prop } ) &&
1393             length( $re->{ $prop } ) )
1394             {
1395 168         427 $info->{ $prop } = $re->{ $prop };
1396             }
1397             }
1398              
1399 103 50 33     546 if( exists( $re->{locale_bcp47} ) &&
      33        
1400             defined( $re->{locale_bcp47} ) &&
1401             length( $re->{locale_bcp47} ) )
1402             {
1403 103         179 my $offset = length( $re->{locale_bcp47} );
1404 103 100       312 $offset++ if( substr( $this, $offset, 1 ) eq '-' );
1405 103         239 substr( $this, 0, $offset, '' );
1406             }
1407              
1408 103 50 66     566 if( ( exists( $re->{ext_transform} ) &&
      66        
      33        
      33        
      66        
1409             defined( $re->{ext_transform} ) &&
1410             length( $re->{ext_transform} ) ) ||
1411             ( exists( $re->{transform_options} ) &&
1412             defined( $re->{transform_options} ) &&
1413             length( $re->{transform_options} ) ) )
1414             {
1415 16         29 my $t;
1416 16 50 33     96 if( exists( $re->{ext_transform} ) &&
    0 0        
1417             defined( $re->{ext_transform} ) )
1418             {
1419 16   50     74 my $t_locale = $self->new( $re->{ext_transform_locale} ) ||
1420             return( $self->pass_error );
1421 16         49 $info->{transform_locale} = $t_locale;
1422 16         33 $t = $re->{ext_transform};
1423 16         61 my $offset = length( "t-${t_locale}" );
1424 16 100 66     117 if( length( $re->{ext_transform} ) > $offset &&
1425             substr( $re->{ext_transform}, $offset, 1 ) eq '-' )
1426             {
1427 10         20 $offset++;
1428             }
1429 16         94 substr( $t, 0, $offset, '' );
1430             }
1431             elsif( exists( $re->{transform_options} ) &&
1432             defined( $re->{transform_options} ) )
1433             {
1434 0         0 $t = $re->{transform_options};
1435             }
1436 16         46 $info->{transform_ext} = [];
1437 16         261 my @parts = split( /\-?($LOCALE_TRANSFORM_PARAMETERS_RE)\-/, $t );
1438             # First array element is undef, because it is the beginning of the string.
1439 16         32 shift( @parts );
1440 16         55 for( my $i = 0; $i < scalar( @parts ); $i += 2 )
1441             {
1442 15         31 my $n = $parts[$i];
1443 15         33 my $v = $parts[$i + 1];
1444 15 50       117 if( exists( $info->{ $n } ) )
    50          
1445             {
1446 0 0 0     0 warn( "The Transform extension \"${n}\" was previously defined with \"", ( $info->{ $n } // 'undef' ), "\", overwriting it with \"", ( $v // 'undef' ), "\"" ) if( warnings::enabled() );
      0        
1447             }
1448             elsif( !$self->can( $n ) )
1449             {
1450 0 0       0 warn( "The Transform extension specified \"${n}\" is unsupported." ) if( warnings::enabled() );
1451             }
1452 15         35 $info->{ $n } = $v;
1453 15         27 push( @{$info->{transform_ext}}, $n );
  15         79  
1454             }
1455             }
1456              
1457 103 50 66     637 if( ( exists( $re->{ext_unicode} ) &&
      66        
      33        
      33        
      66        
1458             defined( $re->{ext_unicode} ) &&
1459             length( $re->{ext_unicode} ) ) ||
1460             ( exists( $re->{collation_options} ) &&
1461             defined( $re->{collation_options} ) &&
1462             length( $re->{collation_options} ) ) )
1463             {
1464 9         21 $info->{unicode_ext} = [];
1465             # ca, co, cf, cu, etc... or collation options such as: ka, kb, kc, etc.
1466             # my @parts = split( /\-([a-z]{2})\-/, '-' . ( $re->{ext_unicode_subtag} // $re->{collation_options} ) );
1467 9 50       41 substr( $re->{ext_unicode}, 0, 1, '' ) if( substr( $re->{ext_unicode}, 0, 2 ) eq 'u-' );
1468 9   33     85 my @parts = split( /\-([a-z]{2})\-/, ( $re->{ext_unicode} // ( '-' . $re->{collation_options} ) ) );
1469 9         17 shift( @parts );
1470 9         34 for( my $i = 0; $i < scalar( @parts ); $i += 2 )
1471             {
1472 17         27 my $n = $parts[$i];
1473 17         25 my $v = $parts[$i + 1];
1474 17 50       98 if( exists( $info->{ $n } ) )
    50          
1475             {
1476 0 0 0     0 warn( "The Unicode extension \"${n}\" was previously defined with \"", ( $info->{ $n } // 'undef' ), "\", overwriting it with \"", ( $v // 'undef' ), "\"" ) if( warnings::enabled() );
      0        
1477             }
1478             elsif( !$self->can( $n ) )
1479             {
1480 0 0       0 warn( "The Unicode extension specified \"${n}\" is unsupported." ) if( warnings::enabled() );
1481             }
1482 17         35 $info->{ $n } = $v;
1483 17         23 push( @{$info->{unicode_ext}}, $n );
  17         66  
1484             }
1485             }
1486              
1487 103 0 33     314 if( exists( $re->{extension} ) &&
      33        
1488             defined( $re->{extension} ) &&
1489             length( $re->{extension} ) )
1490             {
1491 0         0 my $tag = $re->{singleton};
1492             $info->{singleton} =
1493             {
1494 0         0 $tag => {},
1495             };
1496 0         0 $info->{singleton}->{ $tag }->{subtags} = [];
1497 0         0 my @parts = split( /\-([a-zA-Z0-9]{2,8})\-/, $re->{subtag} );
1498 0         0 for( my $i = 0; $i < scalar( @parts ); $i += 2 )
1499             {
1500 0         0 my $n = $parts[$i];
1501 0         0 my $v = $parts[$i + 1];
1502 0         0 $info->{singleton}->{ $tag }->{ $n } = $v;
1503 0         0 push( @{$info->{singleton}->{ $tag }->{subtags}}, $n );
  0         0  
1504             }
1505             }
1506              
1507 103 50 66     261 if( exists( $re->{private_extension} ) &&
      66        
1508             defined( $re->{private_extension} ) &&
1509             length( $re->{private_extension} ) )
1510             {
1511 4         12 $info->{private} = $re->{private_subtag};
1512             }
1513 103         628 return( $info );
1514             }
1515              
1516             sub pass_error
1517             {
1518 0     0 0 0 my $self = shift( @_ );
1519 0   0     0 my $pack = ref( $self ) || $self;
1520 0         0 my $opts = {};
1521 0         0 my( $err, $class, $code );
1522 3     3   80 no strict 'refs';
  3         33  
  3         31811  
1523 0 0       0 if( scalar( @_ ) )
1524             {
1525             # Either an hash defining a new error and this will be passed along to error(); or
1526             # an hash with a single property: { class => 'Some::ExceptionClass' }
1527 0 0 0     0 if( scalar( @_ ) == 1 && ref( $_[0] ) eq 'HASH' )
1528             {
1529 0         0 $opts = $_[0];
1530             }
1531             else
1532             {
1533 0 0 0     0 if( scalar( @_ ) > 1 && ref( $_[-1] ) eq 'HASH' )
1534             {
1535 0         0 $opts = pop( @_ );
1536             }
1537 0         0 $err = $_[0];
1538             }
1539             }
1540 0 0 0     0 $err = $opts->{error} if( !defined( $err ) && CORE::exists( $opts->{error} ) && defined( $opts->{error} ) && CORE::length( $opts->{error} ) );
      0        
      0        
1541             # We set $class only if the hash provided is a one-element hash and not an error-defining hash
1542 0 0 0     0 $class = $opts->{class} if( CORE::exists( $opts->{class} ) && defined( $opts->{class} ) && CORE::length( $opts->{class} ) );
      0        
1543 0 0 0     0 $code = $opts->{code} if( CORE::exists( $opts->{code} ) && defined( $opts->{code} ) && CORE::length( $opts->{code} ) );
      0        
1544            
1545             # called with no argument, most likely from the same class to pass on an error
1546             # set up earlier by another method; or
1547             # with an hash containing just one argument class => 'Some::ExceptionClass'
1548 0 0 0     0 if( !defined( $err ) && ( !scalar( @_ ) || defined( $class ) ) )
    0 0        
      0        
      0        
      0        
1549             {
1550             # $error is a previous erro robject
1551 0 0       0 my $error = ref( $self ) ? $self->{error} : length( ${ $pack . '::ERROR' } ) ? ${ $pack . '::ERROR' } : undef;
  0 0       0  
  0         0  
1552 0 0       0 if( !defined( $error ) )
1553             {
1554 0         0 warn( "No error object provided and no previous error set either! It seems the previous method call returned a simple undef" );
1555             }
1556             else
1557             {
1558 0 0       0 $err = ( defined( $class ) ? bless( $error => $class ) : $error );
1559 0 0       0 $err->code( $code ) if( defined( $code ) );
1560             }
1561             }
1562             elsif( defined( $err ) &&
1563             Scalar::Util::blessed( $err ) &&
1564             ( scalar( @_ ) == 1 ||
1565             ( scalar( @_ ) == 2 && defined( $class ) )
1566             ) )
1567             {
1568 0 0       0 $self->{error} = ${ $pack . '::ERROR' } = ( defined( $class ) ? bless( $err => $class ) : $err );
  0         0  
1569 0 0 0     0 $self->{error}->code( $code ) if( defined( $code ) && $self->{error}->can( 'code' ) );
1570            
1571 0 0 0     0 if( $self->{fatal} || ( defined( ${"${class}\::FATAL_EXCEPTIONS"} ) && ${"${class}\::FATAL_EXCEPTIONS"} ) )
  0   0     0  
  0         0  
1572             {
1573 0         0 die( $self->{error} );
1574             }
1575             }
1576             # If the error provided is not an object, we call error to create one
1577             else
1578             {
1579 0         0 return( $self->error( @_ ) );
1580             }
1581            
1582 0 0       0 if( want( 'OBJECT' ) )
1583             {
1584 0         0 rreturn( Locale::Unicode::NullObject->new );
1585             }
1586 0         0 return;
1587             }
1588              
1589             # x-something
1590 52     52 1 2453 sub private { return( shift->reset(@_)->_set_get_prop( 'private', @_ ) ); }
1591              
1592             sub privateuse { return( shift->reset(@_)->_set_get_prop( {
1593             field => 'privateuse',
1594             on_update => sub
1595             {
1596 2     2   4 $_[0]->{language} = undef;
1597 2         5 $_[0]->{language3} = undef;
1598 2         5 $_[0]->{grandfathered_irregular} = undef;
1599 2         5 $_[0]->{grandfathered_regular} = undef;
1600             },
1601 93     93 1 18223 }, @_ ) ); }
1602              
1603             sub region { return( shift->reset(@_)->_set_get_prop({
1604             field => 'region',
1605 0     0   0 on_update => sub{ $_[0]->{country_code} = undef; },
1606 35     35 1 106 }, @_ ) ); }
1607              
1608             # u-rg
1609 48     48 1 132 sub region_override { return( shift->reset(@_)->_set_get_prop( 'region_override', @_ ) ); }
1610              
1611             # u-rg
1612 0     0 1 0 sub rg { return( shift->region_override( @_ ) ); }
1613              
1614             sub reset
1615             {
1616 2731     2731 1 4840 my $self = shift( @_ );
1617 2731 100 100     10021 if( !CORE::length( $self->{_reset} // '' ) && scalar( @_ ) )
      100        
1618             {
1619 88         223 $self->{_reset} = scalar( @_ );
1620             }
1621 2731         12729 return( $self );
1622             }
1623              
1624             # t-s0
1625 0     0 1 0 sub s0 { return( shift->source( @_ ) ); }
1626              
1627 94     94 1 9165 sub script { return( shift->reset(@_)->_set_get_prop( 'script', @_ ) ); }
1628              
1629             # u-ss
1630 48     48 1 134 sub sentence_break { return( shift->reset(@_)->_set_get_prop( 'sentence_break', @_ ) ); }
1631              
1632             # u-kv
1633 0     0 1 0 sub shiftedGroup { return( shift->colValue( @_ ) ); }
1634              
1635             # t-s0
1636 48     48 1 153 sub source { return( shift->reset(@_)->_set_get_prop( 'source', @_ ) ); }
1637              
1638             # u-sd
1639 50     50 1 819 sub sd { return( shift->subdivision( @_ ) ); }
1640              
1641             # u-ss
1642 0     0 1 0 sub ss { return( shift->sentence_break( @_ ) ); }
1643              
1644             # u-sd
1645 50     50 1 123 sub subdivision { return( shift->reset(@_)->_set_get_prop( 'subdivision', @_ ) ); }
1646              
1647             # t-t0
1648 3     3 1 3458 sub t0 { return( shift->translation( @_ ) ); }
1649              
1650             # t-x0
1651 53     53 1 140 sub t_private { return( shift->reset(@_)->_set_get_prop( 't_private', @_ ) ); }
1652              
1653             sub territory
1654             {
1655 11     11 1 3869 my $self = shift( @_ );
1656 11 100       42 if( @_ )
1657             {
1658 2         6 my $val = shift( @_ );
1659 2 50       5 if( defined( $val ) )
1660             {
1661 2 50       13 if( $val =~ /^([a-zA-Z]{2})$/ )
    0          
1662             {
1663 2         11 $self->country_code( uc( $1 ) );
1664             }
1665             elsif( $val =~ /^(\d{3})$/ )
1666             {
1667 0         0 $self->region( $1 );
1668             }
1669             else
1670             {
1671 0         0 return( $self->error( "Invalid value for territory. It must be either a 2-characters ISO3166 code or a 3-digits region code." ) );
1672             }
1673             }
1674             else
1675             {
1676 0         0 $self->country_code( undef );
1677 0         0 $self->region( undef );
1678             }
1679             }
1680 11   66     42 return( $self->country_code || $self->region );
1681             }
1682              
1683             # u-tz
1684 54     54 1 160 sub time_zone { return( shift->reset(@_)->_set_get_prop( 'time_zone', @_ ) ); }
1685              
1686             # u-tz
1687 0     0 1 0 sub timezone { return( shift->reset(@_)->_set_get_prop( 'time_zone', @_ ) ); }
1688              
1689             sub transform
1690             {
1691 5     5 1 27 my $self = shift( @_ );
1692 5 100       16 if( @_ )
1693             {
1694 3         7 my $val = shift( @_ );
1695 3 50       8 if( defined( $val ) )
1696             {
1697 3 100 33     22 unless( Scalar::Util::blessed( $val ) &&
      66        
1698             $val->isa( ref( $self ) || $self ) )
1699             {
1700 2   50     7 my $locale = $self->new( $val ) || return( $self->pass_error );
1701 2         9 my $core = $locale->core;
1702 2 50       13 $locale = $self->new( $core ) unless( $core eq $locale );
1703 2         7 $val = $locale;
1704             }
1705             }
1706 3         10 $self->transform_locale( $val );
1707             }
1708 5         30 return( $self );
1709             }
1710              
1711             # t-und-Latn
1712 68     68 1 6807 sub transform_locale { return( shift->reset(@_)->_set_get_prop({
1713             field => 'transform_locale',
1714             isa => 'Locale::Unicode',
1715             }, @_ ) ); }
1716              
1717             # t-t0
1718 56     56 1 176 sub translation { return( shift->reset(@_)->_set_get_prop( 'translation', @_ ) ); }
1719              
1720 0     0 1 0 sub true { return( $Locale::Unicode::Boolean::true ); }
1721              
1722             # u-tz
1723 4     4 1 2129 sub tz { return( shift->time_zone( @_ ) ); }
1724              
1725             # Returns an Olson IANA time zone name as a string for a given CLDR timezone ID
1726             sub tz_id2name
1727             {
1728 1     1 1 4931 my $self = shift( @_ );
1729 1   50     5 my $id = shift( @_ ) || return( $self->error( "No CLDR timezone ID was provided." ) );
1730 1   50     6 my $def = $self->tz_info( $id ) || return( '' );
1731 1 50 50     13 if( !defined( $def->{tz} ) ||
      33        
1732             !length( $def->{tz} // '' ) )
1733             {
1734 0         0 return( $self->error( "No property 'tz' could be found in our database for CLDR timezone ID '$id'. It seems our database is corrupted." ) );
1735             }
1736 1         7 return( $def->{tz} );
1737             }
1738              
1739             # Returns an array object of Olson IANA time zones for a given CLDR timezone ID
1740             sub tz_id2names
1741             {
1742 1     1 1 4 my $self = shift( @_ );
1743 1   50     26 my $id = shift( @_ ) || return( $self->error( "No CLDR timezone ID was provided." ) );
1744 1         2 my $a = [];
1745 1         5 my $def = $self->tz_info( $id );
1746 1 50       8 if( !defined( $def ) )
    50          
1747             {
1748 0         0 return( $self->pass_error );
1749             }
1750             elsif( !$def )
1751             {
1752 0         0 return( $a );
1753             }
1754 1 50 50     12 push( @$a, @{$def->{alias}} ) if( exists( $def->{alias} ) && ( ref( $def->{alias} ) || '' ) eq 'ARRAY' );
  1   33     5  
1755 1         4 return( $a );
1756             }
1757              
1758             sub tz_info
1759             {
1760 3     3 1 1100 my $self = shift( @_ );
1761 3   50     11 my $id = shift( @_ ) || return( $self->error( "No CLDR timezone ID was provided." ) );
1762 3         8 $id = lc( $id );
1763 3 50       13 return( '' ) if( !exists( $TZ_DICT->{ $id } ) );
1764 3         6 my %ref = %{$TZ_DICT->{ $id }};
  3         30  
1765 3         12 return( \%ref );
1766             }
1767              
1768             # Returns a CLDR timezone ID for a given IANA Olson timezone name
1769             sub tz_name2id
1770             {
1771 1     1 1 1258 my $self = shift( @_ );
1772 1   50     6 my $name = shift( @_ ) || return( $self->error( "No CLDR timezone ID was provided." ) );
1773 1 50 33     24 if( !exists( $TZ_NAME2ID->{ $name } ) ||
      50        
      33        
1774             !defined( $TZ_NAME2ID->{ $name } ) ||
1775             !length( $TZ_NAME2ID->{ $name } // '' ) )
1776             {
1777 0         0 return( '' );
1778             }
1779 1         5 return( $TZ_NAME2ID->{ $name } );
1780             }
1781              
1782             # u-mu
1783 48     48 1 135 sub unit { return( shift->reset(@_)->_set_get_prop( 'unit', @_ ) ); }
1784              
1785             # u-va
1786 48     48 1 138 sub va { return( shift->reset(@_)->_set_get_prop( 'va', @_ ) ); }
1787              
1788             # u-va
1789 84     84 1 1545 sub variant { return( shift->reset(@_)->_set_get_prop( 'variant', @_ ) ); }
1790              
1791             sub variants
1792             {
1793 6     6 1 15 my $self = shift( @_ );
1794 6         9 my $variants = [];
1795 6 100       19 if( my $variant = $self->variant )
1796             {
1797 4         20 $variants = [split( /-/, $variant )];
1798             }
1799 6         45 return( $variants );
1800             }
1801              
1802             # u-vt
1803 0     0 1 0 sub vt { return( shift->colVariableTop( @_ ) ); }
1804              
1805             # t-x0
1806 2     2 1 2270 sub x0 { return( shift->t_private( @_ ) ); }
1807              
1808             sub _set_get_prop
1809             {
1810 2860     2860   4561 my $self = shift( @_ );
1811 2860   50     6148 my $field = shift( @_ ) ||
1812             return( $self->error( "No field was provided." ) );
1813 2860         4247 my( $re, $type, $isa, $on_update );
1814 2860 100       6730 if( ref( $field ) eq 'HASH' )
1815             {
1816 1194         1854 my $def = $field;
1817 1194   50     3006 $field = $def->{field} || die( "No 'field' property was provided in the field dictionary hash reference." );
1818 1194 100 66     6524 if( exists( $def->{regexp} ) &&
    100 66        
      66        
      66        
1819             defined( $def->{regexp} ) &&
1820             ref( $def->{regexp} ) eq 'Regexp' )
1821             {
1822 344         604 $re = $def->{regexp};
1823             }
1824             elsif( exists( $def->{type} ) &&
1825             defined( $def->{type} ) &&
1826             length( $def->{type} ) )
1827             {
1828 240         360 $type = $def->{type};
1829             }
1830 1194 50 66     2959 if( exists( $def->{isa} ) &&
      66        
1831             defined( $def->{isa} ) &&
1832             length( $def->{isa} ) )
1833             {
1834 68         110 $isa = $def->{isa};
1835             }
1836 1194 50 66     4707 if( exists( $def->{on_update} ) &&
      66        
1837             defined( $def->{on_update} ) &&
1838             ref( $def->{on_update} ) eq 'CODE' )
1839             {
1840 542         1037 $on_update = $def->{on_update};
1841             }
1842             }
1843 2860 100       5326 if( @_ )
1844             {
1845 204         402 my $val = shift( @_ );
1846 204 100 66     715 if( defined( $val ) &&
1847             length( $val ) )
1848             {
1849 201 50 66     1377 if( defined( $re ) &&
    50 33        
    100          
1850             $val !~ /^$re$/ )
1851             {
1852 0         0 return( $self->error( "Invalid value provided for \"${field}\": ${val}" ) );
1853             }
1854             elsif( defined( $type ) &&
1855             $type eq 'boolean' )
1856             {
1857 0         0 $val = lc( $val );
1858 0 0       0 if( $val =~ /^(?:yes|no)$/i )
    0          
    0          
1859             {
1860 0         0 $self->{_bool_types}->{ $field } = 'literal';
1861 0 0       0 $val = ( $val eq 'yes' ? $self->true : $self->false );
1862             }
1863             elsif( $val =~ /^(?:true|false)$/i )
1864             {
1865 0         0 $self->{_bool_types}->{ $field } = 'logic';
1866 0 0       0 $val = ( $val eq 'true' ? $self->true : $self->false );
1867             }
1868             elsif( $val =~ /^(?:1|0)$/ )
1869             {
1870 0         0 $self->{_bool_types}->{ $field } = 'logic';
1871 0 0       0 $val = ( $val ? $self->true : $self->false );
1872             }
1873             else
1874             {
1875 0 0       0 warn( "Unexpected value used as boolean for attribute \"${field}\": ${val}" ) if( warnings::enabled() );
1876 0 0       0 $val = ( $val ? $self->true : $self->false );
1877             }
1878             }
1879             elsif( defined( $isa ) )
1880             {
1881 12 50 33     111 if( !Scalar::Util::blessed( $val ) ||
      33        
1882             ( Scalar::Util::blessed( $val ) && !$val->isa( $isa ) ) )
1883             {
1884 0         0 return( $self->error( "Value provided is not an ${isa} object." ) );
1885             }
1886             }
1887              
1888 201 100       371 if( defined( $on_update ) )
1889             {
1890 126         172 local $@;
1891 126         228 eval{ $on_update->( $self, $val ) };
  126         245  
1892 126 50       351 if( $@ )
1893             {
1894 0         0 return( $self->error( "Error setting value \"${val}\" for \"{field}\": $@" ) );
1895             }
1896             }
1897             }
1898 204         486 $self->{ $field } = $val
1899             }
1900             # So chaining works
1901 2860 100       6789 rreturn( $self ) if( want( 'OBJECT' ) );
1902             # Returns undef in scalar context and an empty list in list context
1903 2859 100       242656 return if( !defined( $self->{ $field } ) );
1904 464         2929 return( $self->{ $field } );
1905             }
1906              
1907             sub _get_args_as_hash
1908             {
1909 192     192   341 my $self = shift( @_ );
1910 192         267 my $ref = {};
1911 192 100 66     1100 if( scalar( @_ ) == 1 &&
    50 50        
      66        
1912             defined( $_[0] ) &&
1913             ( ref( $_[0] ) || '' ) eq 'HASH' )
1914             {
1915 88         186 $ref = shift( @_ );
1916             }
1917             elsif( !( scalar( @_ ) % 2 ) )
1918             {
1919 104         264 $ref = { @_ };
1920             }
1921             else
1922             {
1923 0         0 die( "Uneven number of parameters provided." );
1924             }
1925 192         448 return( $ref );
1926             }
1927              
1928             {
1929             # NOTE: $TZ_DICT
1930             $TZ_DICT =
1931             {
1932             adalv => { desc => "Andorra", tz => "Europe/Andorra" },
1933             aedxb => { desc => "Dubai, United Arab Emirates", tz => "Asia/Dubai" },
1934             afkbl => { desc => "Kabul, Afghanistan", tz => "Asia/Kabul" },
1935             aganu => { desc => "Antigua", tz => "America/Antigua" },
1936             aiaxa => { desc => "Anguilla", tz => "America/Anguilla" },
1937             altia => { desc => "Tirane, Albania", tz => "Europe/Tirane" },
1938             amevn => { desc => "Yerevan, Armenia", tz => "Asia/Yerevan" },
1939             ancur => { desc => "Cura\xE7ao", tz => "America/Curacao" },
1940             aolad => { desc => "Luanda, Angola", tz => "Africa/Luanda" },
1941             aqams => {
1942             deprecated => 1,
1943             desc => "Amundsen-Scott Station, South Pole",
1944             preferred => "nzakl",
1945             },
1946             aqcas => { desc => "Casey Station, Bailey Peninsula", tz => "Antarctica/Casey" },
1947             aqdav => { desc => "Davis Station, Vestfold Hills", tz => "Antarctica/Davis" },
1948             aqddu => {
1949             desc => "Dumont d'Urville Station, Terre Ad\xE9lie",
1950             tz => "Antarctica/DumontDUrville",
1951             },
1952             aqmaw => { desc => "Mawson Station, Holme Bay", tz => "Antarctica/Mawson" },
1953             aqmcm => { desc => "McMurdo Station, Ross Island", tz => "Antarctica/McMurdo" },
1954             aqplm => { desc => "Palmer Station, Anvers Island", tz => "Antarctica/Palmer" },
1955             aqrot => {
1956             desc => "Rothera Station, Adelaide Island",
1957             tz => "Antarctica/Rothera",
1958             },
1959             aqsyw => {
1960             desc => "Syowa Station, East Ongul Island",
1961             tz => "Antarctica/Syowa",
1962             },
1963             aqtrl => { desc => "Troll Station, Queen Maud Land", tz => "Antarctica/Troll" },
1964             aqvos => { desc => "Vostok Station, Lake Vostok", tz => "Antarctica/Vostok" },
1965             arbue => {
1966             alias => [qw( America/Buenos_Aires America/Argentina/Buenos_Aires )],
1967             desc => "Buenos Aires, Argentina",
1968             tz => "America/Argentina/Buenos_Aires",
1969             },
1970             arcor => {
1971             alias => [qw( America/Cordoba America/Argentina/Cordoba America/Rosario )],
1972             desc => "C\xF3rdoba, Argentina",
1973             tz => "America/Argentina/Cordoba",
1974             },
1975             arctc => {
1976             alias => [qw(
1977             America/Catamarca America/Argentina/Catamarca
1978             America/Argentina/ComodRivadavia
1979             )],
1980             desc => "Catamarca, Argentina",
1981             tz => "America/Argentina/Catamarca",
1982             },
1983             arirj => { desc => "La Rioja, Argentina", tz => "America/Argentina/La_Rioja" },
1984             arjuj => {
1985             alias => [qw( America/Jujuy America/Argentina/Jujuy )],
1986             desc => "Jujuy, Argentina",
1987             tz => "America/Argentina/Jujuy",
1988             },
1989             arluq => { desc => "San Luis, Argentina", tz => "America/Argentina/San_Luis" },
1990             armdz => {
1991             alias => [qw( America/Mendoza America/Argentina/Mendoza )],
1992             desc => "Mendoza, Argentina",
1993             tz => "America/Argentina/Mendoza",
1994             },
1995             arrgl => {
1996             desc => "R\xEDo Gallegos, Argentina",
1997             tz => "America/Argentina/Rio_Gallegos",
1998             },
1999             arsla => { desc => "Salta, Argentina", tz => "America/Argentina/Salta" },
2000             artuc => { desc => "Tucum\xE1n, Argentina", tz => "America/Argentina/Tucuman" },
2001             aruaq => { desc => "San Juan, Argentina", tz => "America/Argentina/San_Juan" },
2002             arush => { desc => "Ushuaia, Argentina", tz => "America/Argentina/Ushuaia" },
2003             asppg => {
2004             alias => [qw( Pacific/Pago_Pago Pacific/Samoa US/Samoa )],
2005             desc => "Pago Pago, American Samoa",
2006             tz => "Pacific/Pago_Pago",
2007             },
2008             atvie => { desc => "Vienna, Austria", tz => "Europe/Vienna" },
2009             auadl => {
2010             alias => [qw( Australia/Adelaide Australia/South )],
2011             desc => "Adelaide, Australia",
2012             tz => "Australia/Adelaide",
2013             },
2014             aubhq => {
2015             alias => [qw( Australia/Broken_Hill Australia/Yancowinna )],
2016             desc => "Broken Hill, Australia",
2017             tz => "Australia/Broken_Hill",
2018             },
2019             aubne => {
2020             alias => [qw( Australia/Brisbane Australia/Queensland )],
2021             desc => "Brisbane, Australia",
2022             tz => "Australia/Brisbane",
2023             },
2024             audrw => {
2025             alias => [qw( Australia/Darwin Australia/North )],
2026             desc => "Darwin, Australia",
2027             tz => "Australia/Darwin",
2028             },
2029             aueuc => { desc => "Eucla, Australia", tz => "Australia/Eucla" },
2030             auhba => {
2031             alias => [qw( Australia/Hobart Australia/Tasmania Australia/Currie )],
2032             desc => "Hobart, Australia",
2033             tz => "Australia/Hobart",
2034             },
2035             aukns => { deprecated => 1, desc => "Currie, Australia", preferred => "auhba" },
2036             auldc => { desc => "Lindeman Island, Australia", tz => "Australia/Lindeman" },
2037             auldh => {
2038             alias => [qw( Australia/Lord_Howe Australia/LHI )],
2039             desc => "Lord Howe Island, Australia",
2040             tz => "Australia/Lord_Howe",
2041             },
2042             aumel => {
2043             alias => [qw( Australia/Melbourne Australia/Victoria )],
2044             desc => "Melbourne, Australia",
2045             tz => "Australia/Melbourne",
2046             },
2047             aumqi => {
2048             desc => "Macquarie Island Station, Macquarie Island",
2049             tz => "Antarctica/Macquarie",
2050             },
2051             auper => {
2052             alias => [qw( Australia/Perth Australia/West )],
2053             desc => "Perth, Australia",
2054             tz => "Australia/Perth",
2055             },
2056             ausyd => {
2057             alias => [qw(
2058             Australia/Sydney Australia/ACT Australia/Canberra
2059             Australia/NSW
2060             )],
2061             desc => "Sydney, Australia",
2062             tz => "Australia/Sydney",
2063             },
2064             awaua => { desc => "Aruba", tz => "America/Aruba" },
2065             azbak => { desc => "Baku, Azerbaijan", tz => "Asia/Baku" },
2066             basjj => { desc => "Sarajevo, Bosnia and Herzegovina", tz => "Europe/Sarajevo" },
2067             bbbgi => { desc => "Barbados", tz => "America/Barbados" },
2068             bddac => {
2069             alias => [qw( Asia/Dhaka Asia/Dacca )],
2070             desc => "Dhaka, Bangladesh",
2071             tz => "Asia/Dhaka",
2072             },
2073             bebru => { desc => "Brussels, Belgium", tz => "Europe/Brussels" },
2074             bfoua => { desc => "Ouagadougou, Burkina Faso", tz => "Africa/Ouagadougou" },
2075             bgsof => { desc => "Sofia, Bulgaria", tz => "Europe/Sofia" },
2076             bhbah => { desc => "Bahrain", tz => "Asia/Bahrain" },
2077             bibjm => { desc => "Bujumbura, Burundi", tz => "Africa/Bujumbura" },
2078             bjptn => { desc => "Porto-Novo, Benin", tz => "Africa/Porto-Novo" },
2079             bmbda => { desc => "Bermuda", tz => "Atlantic/Bermuda" },
2080             bnbwn => { desc => "Brunei", tz => "Asia/Brunei" },
2081             bolpb => { desc => "La Paz, Bolivia", tz => "America/La_Paz" },
2082             bqkra => {
2083             desc => "Bonaire, Sint Estatius and Saba",
2084             tz => "America/Kralendijk",
2085             },
2086             braux => { desc => "Aragua\xEDna, Brazil", tz => "America/Araguaina" },
2087             brbel => { desc => "Bel\xE9m, Brazil", tz => "America/Belem" },
2088             brbvb => { desc => "Boa Vista, Brazil", tz => "America/Boa_Vista" },
2089             brcgb => { desc => "Cuiab\xE1, Brazil", tz => "America/Cuiaba" },
2090             brcgr => { desc => "Campo Grande, Brazil", tz => "America/Campo_Grande" },
2091             brern => { desc => "Eirunep\xE9, Brazil", tz => "America/Eirunepe" },
2092             brfen => {
2093             alias => [qw( America/Noronha Brazil/DeNoronha )],
2094             desc => "Fernando de Noronha, Brazil",
2095             tz => "America/Noronha",
2096             },
2097             brfor => { desc => "Fortaleza, Brazil", tz => "America/Fortaleza" },
2098             brmao => {
2099             alias => [qw( America/Manaus Brazil/West )],
2100             desc => "Manaus, Brazil",
2101             tz => "America/Manaus",
2102             },
2103             brmcz => { desc => "Macei\xF3, Brazil", tz => "America/Maceio" },
2104             brpvh => { desc => "Porto Velho, Brazil", tz => "America/Porto_Velho" },
2105             brrbr => {
2106             alias => [qw( America/Rio_Branco America/Porto_Acre Brazil/Acre )],
2107             desc => "Rio Branco, Brazil",
2108             tz => "America/Rio_Branco",
2109             },
2110             brrec => { desc => "Recife, Brazil", tz => "America/Recife" },
2111             brsao => {
2112             alias => [qw( America/Sao_Paulo Brazil/East )],
2113             desc => "S\xE3o Paulo, Brazil",
2114             tz => "America/Sao_Paulo",
2115             },
2116             brssa => { desc => "Bahia, Brazil", tz => "America/Bahia" },
2117             brstm => { desc => "Santar\xE9m, Brazil", tz => "America/Santarem" },
2118             bsnas => { desc => "Nassau, Bahamas", tz => "America/Nassau" },
2119             btthi => {
2120             alias => [qw( Asia/Thimphu Asia/Thimbu )],
2121             desc => "Thimphu, Bhutan",
2122             tz => "Asia/Thimphu",
2123             },
2124             bwgbe => { desc => "Gaborone, Botswana", tz => "Africa/Gaborone" },
2125             bymsq => { desc => "Minsk, Belarus", tz => "Europe/Minsk" },
2126             bzbze => { desc => "Belize", tz => "America/Belize" },
2127             cacfq => { desc => "Creston, Canada", tz => "America/Creston" },
2128             caedm => {
2129             alias => [qw( America/Edmonton Canada/Mountain America/Yellowknife )],
2130             desc => "Edmonton, Canada",
2131             tz => "America/Edmonton",
2132             },
2133             caffs => { deprecated => 1, desc => "Rainy River, Canada", preferred => "cawnp" },
2134             cafne => { desc => "Fort Nelson, Canada", tz => "America/Fort_Nelson" },
2135             caglb => { desc => "Glace Bay, Canada", tz => "America/Glace_Bay" },
2136             cagoo => { desc => "Goose Bay, Canada", tz => "America/Goose_Bay" },
2137             cahal => {
2138             alias => [qw( America/Halifax Canada/Atlantic )],
2139             desc => "Halifax, Canada",
2140             tz => "America/Halifax",
2141             },
2142             caiql => {
2143             alias => [qw( America/Iqaluit America/Pangnirtung )],
2144             desc => "Iqaluit, Canada",
2145             tz => "America/Iqaluit",
2146             },
2147             camon => { desc => "Moncton, Canada", tz => "America/Moncton" },
2148             camtr => { deprecated => 1, desc => "Montreal, Canada", preferred => "cator" },
2149             canpg => { deprecated => 1, desc => "Nipigon, Canada", preferred => "cator" },
2150             capnt => { deprecated => 1, desc => "Pangnirtung, Canada", preferred => "caiql" },
2151             careb => { desc => "Resolute, Canada", tz => "America/Resolute" },
2152             careg => {
2153             alias => [qw( America/Regina Canada/East-Saskatchewan Canada/Saskatchewan )],
2154             desc => "Regina, Canada",
2155             tz => "America/Regina",
2156             },
2157             casjf => {
2158             alias => [qw( America/St_Johns Canada/Newfoundland )],
2159             desc => "St. John's, Canada",
2160             tz => "America/St_Johns",
2161             },
2162             cathu => { deprecated => 1, desc => "Thunder Bay, Canada", preferred => "cator" },
2163             cator => {
2164             alias => [qw(
2165             America/Toronto America/Montreal Canada/Eastern
2166             America/Nipigon America/Thunder_Bay
2167             )],
2168             desc => "Toronto, Canada",
2169             tz => "America/Toronto",
2170             },
2171             cavan => {
2172             alias => [qw( America/Vancouver Canada/Pacific )],
2173             desc => "Vancouver, Canada",
2174             tz => "America/Vancouver",
2175             },
2176             cawnp => {
2177             alias => [qw( America/Winnipeg Canada/Central America/Rainy_River )],
2178             desc => "Winnipeg, Canada",
2179             tz => "America/Winnipeg",
2180             },
2181             caybx => { desc => "Blanc-Sablon, Canada", tz => "America/Blanc-Sablon" },
2182             caycb => { desc => "Cambridge Bay, Canada", tz => "America/Cambridge_Bay" },
2183             cayda => { desc => "Dawson, Canada", tz => "America/Dawson" },
2184             caydq => { desc => "Dawson Creek, Canada", tz => "America/Dawson_Creek" },
2185             cayek => { desc => "Rankin Inlet, Canada", tz => "America/Rankin_Inlet" },
2186             cayev => { desc => "Inuvik, Canada", tz => "America/Inuvik" },
2187             cayxy => {
2188             alias => [qw( America/Whitehorse Canada/Yukon )],
2189             desc => "Whitehorse, Canada",
2190             tz => "America/Whitehorse",
2191             },
2192             cayyn => { desc => "Swift Current, Canada", tz => "America/Swift_Current" },
2193             cayzf => { deprecated => 1, desc => "Yellowknife, Canada", preferred => "caedm" },
2194             cayzs => {
2195             alias => [qw( America/Coral_Harbour America/Atikokan )],
2196             desc => "Atikokan, Canada",
2197             tz => "America/Atikokan",
2198             },
2199             cccck => { desc => "Cocos (Keeling) Islands", tz => "Indian/Cocos" },
2200             cdfbm => {
2201             desc => "Lubumbashi, Democratic Republic of the Congo",
2202             tz => "Africa/Lubumbashi",
2203             },
2204             cdfih => {
2205             desc => "Kinshasa, Democratic Republic of the Congo",
2206             tz => "Africa/Kinshasa",
2207             },
2208             cfbgf => { desc => "Bangui, Central African Republic", tz => "Africa/Bangui" },
2209             cgbzv => {
2210             desc => "Brazzaville, Republic of the Congo",
2211             tz => "Africa/Brazzaville",
2212             },
2213             chzrh => { desc => "Zurich, Switzerland", tz => "Europe/Zurich" },
2214             ciabj => { desc => "Abidjan, C\xF4te d'Ivoire", tz => "Africa/Abidjan" },
2215             ckrar => { desc => "Rarotonga, Cook Islands", tz => "Pacific/Rarotonga" },
2216             clipc => {
2217             alias => [qw( Pacific/Easter Chile/EasterIsland )],
2218             desc => "Easter Island, Chile",
2219             tz => "Pacific/Easter",
2220             },
2221             clpuq => { desc => "Punta Arenas, Chile", tz => "America/Punta_Arenas" },
2222             clscl => {
2223             alias => [qw( America/Santiago Chile/Continental )],
2224             desc => "Santiago, Chile",
2225             tz => "America/Santiago",
2226             },
2227             cmdla => { desc => "Douala, Cameroon", tz => "Africa/Douala" },
2228             cnckg => { deprecated => 1, desc => "Chongqing, China", preferred => "cnsha" },
2229             cnhrb => { deprecated => 1, desc => "Harbin, China", preferred => "cnsha" },
2230             cnkhg => { deprecated => 1, desc => "Kashgar, China", preferred => "cnurc" },
2231             cnsha => {
2232             alias => [qw( Asia/Shanghai Asia/Chongqing Asia/Chungking Asia/Harbin PRC )],
2233             desc => "Shanghai, China",
2234             tz => "Asia/Shanghai",
2235             },
2236             cnurc => {
2237             alias => [qw( Asia/Urumqi Asia/Kashgar )],
2238             desc => "\xDCr\xFCmqi, China",
2239             tz => "Asia/Urumqi",
2240             },
2241             cobog => { desc => "Bogot\xE1, Colombia", tz => "America/Bogota" },
2242             crsjo => { desc => "Costa Rica", tz => "America/Costa_Rica" },
2243             cst6cdt => {
2244             desc => "POSIX style time zone for US Central Time",
2245             tz => "CST6CDT",
2246             },
2247             cuhav => {
2248             alias => [qw( America/Havana Cuba )],
2249             desc => "Havana, Cuba",
2250             tz => "America/Havana",
2251             },
2252             cvrai => { desc => "Cape Verde", tz => "Atlantic/Cape_Verde" },
2253             cxxch => { desc => "Christmas Island", tz => "Indian/Christmas" },
2254             cyfmg => { desc => "Famagusta, Cyprus", tz => "Asia/Famagusta" },
2255             cynic => {
2256             alias => [qw( Asia/Nicosia Europe/Nicosia )],
2257             desc => "Nicosia, Cyprus",
2258             tz => "Asia/Nicosia",
2259             },
2260             czprg => { desc => "Prague, Czech Republic", tz => "Europe/Prague" },
2261             deber => { desc => "Berlin, Germany", tz => "Europe/Berlin" },
2262             debsngn => { desc => "Busingen, Germany", tz => "Europe/Busingen" },
2263             deprecated => 1,
2264             djjib => { desc => "Djibouti", tz => "Africa/Djibouti" },
2265             dkcph => { desc => "Copenhagen, Denmark", tz => "Europe/Copenhagen" },
2266             dmdom => { desc => "Dominica", tz => "America/Dominica" },
2267             dosdq => {
2268             desc => "Santo Domingo, Dominican Republic",
2269             tz => "America/Santo_Domingo",
2270             },
2271             dzalg => { desc => "Algiers, Algeria", tz => "Africa/Algiers" },
2272             ecgps => { desc => "Gal\xE1pagos Islands, Ecuador", tz => "Pacific/Galapagos" },
2273             ecgye => { desc => "Guayaquil, Ecuador", tz => "America/Guayaquil" },
2274             eetll => { desc => "Tallinn, Estonia", tz => "Europe/Tallinn" },
2275             egcai => {
2276             alias => [qw( Africa/Cairo Egypt )],
2277             desc => "Cairo, Egypt",
2278             tz => "Africa/Cairo",
2279             },
2280             eheai => { desc => "El Aai\xFAn, Western Sahara", tz => "Africa/El_Aaiun" },
2281             erasm => {
2282             alias => [qw( Africa/Asmera Africa/Asmara )],
2283             desc => "Asmara, Eritrea",
2284             tz => "Africa/Asmara",
2285             },
2286             esceu => { desc => "Ceuta, Spain", tz => "Africa/Ceuta" },
2287             eslpa => { desc => "Canary Islands, Spain", tz => "Atlantic/Canary" },
2288             esmad => { desc => "Madrid, Spain", tz => "Europe/Madrid" },
2289             est5edt => {
2290             desc => "POSIX style time zone for US Eastern Time",
2291             tz => "EST5EDT",
2292             },
2293             etadd => { desc => "Addis Ababa, Ethiopia", tz => "Africa/Addis_Ababa" },
2294             fihel => { desc => "Helsinki, Finland", tz => "Europe/Helsinki" },
2295             fimhq => { desc => "Mariehamn, \xC5land, Finland", tz => "Europe/Mariehamn" },
2296             fjsuv => { desc => "Fiji", tz => "Pacific/Fiji" },
2297             fkpsy => { desc => "Stanley, Falkland Islands", tz => "Atlantic/Stanley" },
2298             fmksa => { desc => "Kosrae, Micronesia", tz => "Pacific/Kosrae" },
2299             fmpni => {
2300             alias => [qw( Pacific/Ponape Pacific/Pohnpei )],
2301             desc => "Pohnpei, Micronesia",
2302             tz => "Pacific/Pohnpei",
2303             },
2304             fmtkk => {
2305             alias => [qw( Pacific/Truk Pacific/Chuuk Pacific/Yap )],
2306             desc => "Chuuk, Micronesia",
2307             tz => "Pacific/Chuuk",
2308             },
2309             fotho => {
2310             alias => [qw( Atlantic/Faeroe Atlantic/Faroe )],
2311             desc => "Faroe Islands",
2312             tz => "Atlantic/Faroe",
2313             },
2314             frpar => { desc => "Paris, France", tz => "Europe/Paris" },
2315             galbv => { desc => "Libreville, Gabon", tz => "Africa/Libreville" },
2316             gaza => {
2317             deprecated => 1,
2318             desc => "Gaza Strip, Palestinian Territories",
2319             preferred => "gazastrp",
2320             },
2321             gazastrp => { desc => "Gaza Strip, Palestinian Territories", tz => "Asia/Gaza" },
2322             gblon => {
2323             alias => [qw( Europe/London Europe/Belfast GB GB-Eire )],
2324             desc => "London, United Kingdom",
2325             tz => "Europe/London",
2326             },
2327             gdgnd => { desc => "Grenada", tz => "America/Grenada" },
2328             getbs => { desc => "Tbilisi, Georgia", tz => "Asia/Tbilisi" },
2329             gfcay => { desc => "Cayenne, French Guiana", tz => "America/Cayenne" },
2330             gggci => { desc => "Guernsey", tz => "Europe/Guernsey" },
2331             ghacc => { desc => "Accra, Ghana", tz => "Africa/Accra" },
2332             gigib => { desc => "Gibraltar", tz => "Europe/Gibraltar" },
2333             gldkshvn => { desc => "Danmarkshavn, Greenland", tz => "America/Danmarkshavn" },
2334             glgoh => {
2335             alias => [qw( America/Godthab America/Nuuk )],
2336             desc => "Nuuk (Godth\xE5b), Greenland",
2337             tz => "America/Nuuk",
2338             },
2339             globy => {
2340             desc => "Ittoqqortoormiit (Scoresbysund), Greenland",
2341             tz => "America/Scoresbysund",
2342             },
2343             glthu => { desc => "Qaanaaq (Thule), Greenland", tz => "America/Thule" },
2344             gmbjl => { desc => "Banjul, Gambia", tz => "Africa/Banjul" },
2345             gmt => {
2346             alias => [qw(
2347             Etc/GMT Etc/GMT+0 Etc/GMT-0 Etc/GMT0 Etc/Greenwich GMT
2348             GMT+0 GMT-0 GMT0 Greenwich
2349             )],
2350             desc => "Greenwich Mean Time",
2351             tz => "Etc/GMT",
2352             },
2353             gncky => { desc => "Conakry, Guinea", tz => "Africa/Conakry" },
2354             gpbbr => { desc => "Guadeloupe", tz => "America/Guadeloupe" },
2355             gpmsb => { desc => "Marigot, Saint Martin", tz => "America/Marigot" },
2356             gpsbh => { desc => "Saint Barth\xE9lemy", tz => "America/St_Barthelemy" },
2357             gqssg => { desc => "Malabo, Equatorial Guinea", tz => "Africa/Malabo" },
2358             grath => { desc => "Athens, Greece", tz => "Europe/Athens" },
2359             gsgrv => {
2360             desc => "South Georgia and the South Sandwich Islands",
2361             tz => "Atlantic/South_Georgia",
2362             },
2363             gtgua => { desc => "Guatemala", tz => "America/Guatemala" },
2364             gugum => { desc => "Guam", tz => "Pacific/Guam" },
2365             gwoxb => { desc => "Bissau, Guinea-Bissau", tz => "Africa/Bissau" },
2366             gygeo => { desc => "Guyana", tz => "America/Guyana" },
2367             hebron => { desc => "West Bank, Palestinian Territories", tz => "Asia/Hebron" },
2368             hkhkg => {
2369             alias => [qw( Asia/Hong_Kong Hongkong )],
2370             desc => "Hong Kong SAR China",
2371             tz => "Asia/Hong_Kong",
2372             },
2373             hntgu => { desc => "Tegucigalpa, Honduras", tz => "America/Tegucigalpa" },
2374             hrzag => { desc => "Zagreb, Croatia", tz => "Europe/Zagreb" },
2375             htpap => { desc => "Port-au-Prince, Haiti", tz => "America/Port-au-Prince" },
2376             hubud => { desc => "Budapest, Hungary", tz => "Europe/Budapest" },
2377             iddjj => { desc => "Jayapura, Indonesia", tz => "Asia/Jayapura" },
2378             idjkt => { desc => "Jakarta, Indonesia", tz => "Asia/Jakarta" },
2379             idmak => {
2380             alias => [qw( Asia/Makassar Asia/Ujung_Pandang )],
2381             desc => "Makassar, Indonesia",
2382             tz => "Asia/Makassar",
2383             },
2384             idpnk => { desc => "Pontianak, Indonesia", tz => "Asia/Pontianak" },
2385             iedub => {
2386             alias => [qw( Europe/Dublin Eire )],
2387             desc => "Dublin, Ireland",
2388             tz => "Europe/Dublin",
2389             },
2390             imdgs => { desc => "Isle of Man", tz => "Europe/Isle_of_Man" },
2391             inccu => {
2392             alias => [qw( Asia/Calcutta Asia/Kolkata )],
2393             desc => "Kolkata, India",
2394             tz => "Asia/Kolkata",
2395             },
2396             iodga => { desc => "Chagos Archipelago", tz => "Indian/Chagos" },
2397             iqbgw => { desc => "Baghdad, Iraq", tz => "Asia/Baghdad" },
2398             irthr => {
2399             alias => [qw( Asia/Tehran Iran )],
2400             desc => "Tehran, Iran",
2401             tz => "Asia/Tehran",
2402             },
2403             isrey => {
2404             alias => [qw( Atlantic/Reykjavik Iceland )],
2405             desc => "Reykjavik, Iceland",
2406             tz => "Atlantic/Reykjavik",
2407             },
2408             itrom => { desc => "Rome, Italy", tz => "Europe/Rome" },
2409             jeruslm => {
2410             alias => [qw( Asia/Jerusalem Asia/Tel_Aviv Israel )],
2411             desc => "Jerusalem",
2412             tz => "Asia/Jerusalem",
2413             },
2414             jesth => { desc => "Jersey", tz => "Europe/Jersey" },
2415             jmkin => {
2416             alias => [qw( America/Jamaica Jamaica )],
2417             desc => "Jamaica",
2418             tz => "America/Jamaica",
2419             },
2420             joamm => { desc => "Amman, Jordan", tz => "Asia/Amman" },
2421             jptyo => {
2422             alias => [qw( Asia/Tokyo Japan )],
2423             desc => "Tokyo, Japan",
2424             tz => "Asia/Tokyo",
2425             },
2426             kenbo => { desc => "Nairobi, Kenya", tz => "Africa/Nairobi" },
2427             kgfru => { desc => "Bishkek, Kyrgyzstan", tz => "Asia/Bishkek" },
2428             khpnh => { desc => "Phnom Penh, Cambodia", tz => "Asia/Phnom_Penh" },
2429             kicxi => { desc => "Kiritimati, Kiribati", tz => "Pacific/Kiritimati" },
2430             kipho => {
2431             alias => [qw( Pacific/Enderbury Pacific/Kanton )],
2432             desc => "Enderbury Island, Kiribati",
2433             tz => "Pacific/Kanton",
2434             },
2435             kitrw => { desc => "Tarawa, Kiribati", tz => "Pacific/Tarawa" },
2436             kmyva => { desc => "Comoros", tz => "Indian/Comoro" },
2437             knbas => { desc => "Saint Kitts", tz => "America/St_Kitts" },
2438             kpfnj => { desc => "Pyongyang, North Korea", tz => "Asia/Pyongyang" },
2439             krsel => {
2440             alias => [qw( Asia/Seoul ROK )],
2441             desc => "Seoul, South Korea",
2442             tz => "Asia/Seoul",
2443             },
2444             kwkwi => { desc => "Kuwait", tz => "Asia/Kuwait" },
2445             kygec => { desc => "Cayman Islands", tz => "America/Cayman" },
2446             kzaau => { desc => "Aqtau, Kazakhstan", tz => "Asia/Aqtau" },
2447             kzakx => { desc => "Aqtobe, Kazakhstan", tz => "Asia/Aqtobe" },
2448             kzala => { desc => "Almaty, Kazakhstan", tz => "Asia/Almaty" },
2449             kzguw => { desc => "Atyrau (Guryev), Kazakhstan", tz => "Asia/Atyrau" },
2450             kzksn => { desc => "Qostanay (Kostanay), Kazakhstan", tz => "Asia/Qostanay" },
2451             kzkzo => { desc => "Kyzylorda, Kazakhstan", tz => "Asia/Qyzylorda" },
2452             kzura => { desc => "Oral, Kazakhstan", tz => "Asia/Oral" },
2453             lavte => { desc => "Vientiane, Laos", tz => "Asia/Vientiane" },
2454             lbbey => { desc => "Beirut, Lebanon", tz => "Asia/Beirut" },
2455             lccas => { desc => "Saint Lucia", tz => "America/St_Lucia" },
2456             livdz => { desc => "Vaduz, Liechtenstein", tz => "Europe/Vaduz" },
2457             lkcmb => { desc => "Colombo, Sri Lanka", tz => "Asia/Colombo" },
2458             lrmlw => { desc => "Monrovia, Liberia", tz => "Africa/Monrovia" },
2459             lsmsu => { desc => "Maseru, Lesotho", tz => "Africa/Maseru" },
2460             ltvno => { desc => "Vilnius, Lithuania", tz => "Europe/Vilnius" },
2461             lulux => { desc => "Luxembourg", tz => "Europe/Luxembourg" },
2462             lvrix => { desc => "Riga, Latvia", tz => "Europe/Riga" },
2463             lytip => {
2464             alias => [qw( Africa/Tripoli Libya )],
2465             desc => "Tripoli, Libya",
2466             tz => "Africa/Tripoli",
2467             },
2468             macas => { desc => "Casablanca, Morocco", tz => "Africa/Casablanca" },
2469             mcmon => { desc => "Monaco", tz => "Europe/Monaco" },
2470             mdkiv => {
2471             alias => [qw( Europe/Chisinau Europe/Tiraspol )],
2472             desc => "Chi\x{15F}in\x{103}u, Moldova",
2473             tz => "Europe/Chisinau",
2474             },
2475             metgd => { desc => "Podgorica, Montenegro", tz => "Europe/Podgorica" },
2476             mgtnr => { desc => "Antananarivo, Madagascar", tz => "Indian/Antananarivo" },
2477             mhkwa => {
2478             alias => [qw( Pacific/Kwajalein Kwajalein )],
2479             desc => "Kwajalein, Marshall Islands",
2480             tz => "Pacific/Kwajalein",
2481             },
2482             mhmaj => { desc => "Majuro, Marshall Islands", tz => "Pacific/Majuro" },
2483             mkskp => { desc => "Skopje, Macedonia", tz => "Europe/Skopje" },
2484             mlbko => {
2485             alias => [qw( Africa/Bamako Africa/Timbuktu )],
2486             desc => "Bamako, Mali",
2487             tz => "Africa/Bamako",
2488             },
2489             mmrgn => {
2490             alias => [qw( Asia/Rangoon Asia/Yangon )],
2491             desc => "Yangon (Rangoon), Burma",
2492             tz => "Asia/Yangon",
2493             },
2494             mncoq => { desc => "Choibalsan, Mongolia", tz => "Asia/Choibalsan" },
2495             mnhvd => { desc => "Khovd (Hovd), Mongolia", tz => "Asia/Hovd" },
2496             mnuln => {
2497             alias => [qw( Asia/Ulaanbaatar Asia/Ulan_Bator )],
2498             desc => "Ulaanbaatar (Ulan Bator), Mongolia",
2499             tz => "Asia/Ulaanbaatar",
2500             },
2501             momfm => {
2502             alias => [qw( Asia/Macau Asia/Macao )],
2503             desc => "Macau SAR China",
2504             tz => "Asia/Macau",
2505             },
2506             mpspn => { desc => "Saipan, Northern Mariana Islands", tz => "Pacific/Saipan" },
2507             mqfdf => { desc => "Martinique", tz => "America/Martinique" },
2508             mrnkc => { desc => "Nouakchott, Mauritania", tz => "Africa/Nouakchott" },
2509             msmni => { desc => "Montserrat", tz => "America/Montserrat" },
2510             mst7mdt => {
2511             desc => "POSIX style time zone for US Mountain Time",
2512             tz => "MST7MDT",
2513             },
2514             mtmla => { desc => "Malta", tz => "Europe/Malta" },
2515             muplu => { desc => "Mauritius", tz => "Indian/Mauritius" },
2516             mvmle => { desc => "Maldives", tz => "Indian/Maldives" },
2517             mwblz => { desc => "Blantyre, Malawi", tz => "Africa/Blantyre" },
2518             mxchi => { desc => "Chihuahua, Mexico", tz => "America/Chihuahua" },
2519             mxcjs => { desc => "Ciudad Ju\xE1rez, Mexico", tz => "America/Ciudad_Juarez" },
2520             mxcun => { desc => "Canc\xFAn, Mexico", tz => "America/Cancun" },
2521             mxhmo => { desc => "Hermosillo, Mexico", tz => "America/Hermosillo" },
2522             mxmam => { desc => "Matamoros, Mexico", tz => "America/Matamoros" },
2523             mxmex => {
2524             alias => [qw( America/Mexico_City Mexico/General )],
2525             desc => "Mexico City, Mexico",
2526             tz => "America/Mexico_City",
2527             },
2528             mxmid => { desc => "M\xE9rida, Mexico", tz => "America/Merida" },
2529             mxmty => { desc => "Monterrey, Mexico", tz => "America/Monterrey" },
2530             mxmzt => {
2531             alias => [qw( America/Mazatlan Mexico/BajaSur )],
2532             desc => "Mazatl\xE1n, Mexico",
2533             tz => "America/Mazatlan",
2534             },
2535             mxoji => { desc => "Ojinaga, Mexico", tz => "America/Ojinaga" },
2536             mxpvr => {
2537             desc => "Bah\xEDa de Banderas, Mexico",
2538             tz => "America/Bahia_Banderas",
2539             },
2540             mxstis => {
2541             deprecated => 1,
2542             desc => "Santa Isabel (Baja California), Mexico",
2543             preferred => "mxtij",
2544             },
2545             mxtij => {
2546             alias => [qw(
2547             America/Tijuana America/Ensenada Mexico/BajaNorte
2548             America/Santa_Isabel
2549             )],
2550             desc => "Tijuana, Mexico",
2551             tz => "America/Tijuana",
2552             },
2553             mykch => { desc => "Kuching, Malaysia", tz => "Asia/Kuching" },
2554             mykul => { desc => "Kuala Lumpur, Malaysia", tz => "Asia/Kuala_Lumpur" },
2555             mzmpm => { desc => "Maputo, Mozambique", tz => "Africa/Maputo" },
2556             nawdh => { desc => "Windhoek, Namibia", tz => "Africa/Windhoek" },
2557             ncnou => { desc => "Noumea, New Caledonia", tz => "Pacific/Noumea" },
2558             nenim => { desc => "Niamey, Niger", tz => "Africa/Niamey" },
2559             nfnlk => { desc => "Norfolk Island", tz => "Pacific/Norfolk" },
2560             nglos => { desc => "Lagos, Nigeria", tz => "Africa/Lagos" },
2561             nimga => { desc => "Managua, Nicaragua", tz => "America/Managua" },
2562             nlams => { desc => "Amsterdam, Netherlands", tz => "Europe/Amsterdam" },
2563             noosl => { desc => "Oslo, Norway", tz => "Europe/Oslo" },
2564             npktm => {
2565             alias => [qw( Asia/Katmandu Asia/Kathmandu )],
2566             desc => "Kathmandu, Nepal",
2567             tz => "Asia/Kathmandu",
2568             },
2569             nrinu => { desc => "Nauru", tz => "Pacific/Nauru" },
2570             nuiue => { desc => "Niue", tz => "Pacific/Niue" },
2571             nzakl => {
2572             alias => [qw( Pacific/Auckland Antarctica/South_Pole NZ )],
2573             desc => "Auckland, New Zealand",
2574             tz => "Pacific/Auckland",
2575             },
2576             nzcht => {
2577             alias => [qw( Pacific/Chatham NZ-CHAT )],
2578             desc => "Chatham Islands, New Zealand",
2579             tz => "Pacific/Chatham",
2580             },
2581             ommct => { desc => "Muscat, Oman", tz => "Asia/Muscat" },
2582             papty => { desc => "Panama", tz => "America/Panama" },
2583             pelim => { desc => "Lima, Peru", tz => "America/Lima" },
2584             pfgmr => {
2585             desc => "Gambiera Islands, French Polynesia",
2586             tz => "Pacific/Gambier",
2587             },
2588             pfnhv => {
2589             desc => "Marquesas Islands, French Polynesia",
2590             tz => "Pacific/Marquesas",
2591             },
2592             pfppt => { desc => "Tahiti, French Polynesia", tz => "Pacific/Tahiti" },
2593             pgpom => {
2594             desc => "Port Moresby, Papua New Guinea",
2595             tz => "Pacific/Port_Moresby",
2596             },
2597             pgraw => {
2598             desc => "Bougainville, Papua New Guinea",
2599             tz => "Pacific/Bougainville",
2600             },
2601             phmnl => { desc => "Manila, Philippines", tz => "Asia/Manila" },
2602             pkkhi => { desc => "Karachi, Pakistan", tz => "Asia/Karachi" },
2603             plwaw => {
2604             alias => [qw( Europe/Warsaw Poland )],
2605             desc => "Warsaw, Poland",
2606             tz => "Europe/Warsaw",
2607             },
2608             pmmqc => { desc => "Saint Pierre and Miquelon", tz => "America/Miquelon" },
2609             pnpcn => { desc => "Pitcairn Islands", tz => "Pacific/Pitcairn" },
2610             prsju => { desc => "Puerto Rico", tz => "America/Puerto_Rico" },
2611             pst8pdt => {
2612             desc => "POSIX style time zone for US Pacific Time",
2613             tz => "PST8PDT",
2614             },
2615             ptfnc => { desc => "Madeira, Portugal", tz => "Atlantic/Madeira" },
2616             ptlis => {
2617             alias => [qw( Europe/Lisbon Portugal )],
2618             desc => "Lisbon, Portugal",
2619             tz => "Europe/Lisbon",
2620             },
2621             ptpdl => { desc => "Azores, Portugal", tz => "Atlantic/Azores" },
2622             pwror => { desc => "Palau", tz => "Pacific/Palau" },
2623             pyasu => { desc => "Asunci\xF3n, Paraguay", tz => "America/Asuncion" },
2624             qadoh => { desc => "Qatar", tz => "Asia/Qatar" },
2625             rereu => { desc => "R\xE9union", tz => "Indian/Reunion" },
2626             robuh => { desc => "Bucharest, Romania", tz => "Europe/Bucharest" },
2627             rsbeg => { desc => "Belgrade, Serbia", tz => "Europe/Belgrade" },
2628             ruasf => { desc => "Astrakhan, Russia", tz => "Europe/Astrakhan" },
2629             rubax => { desc => "Barnaul, Russia", tz => "Asia/Barnaul" },
2630             ruchita => { desc => "Chita Zabaykalsky, Russia", tz => "Asia/Chita" },
2631             rudyr => { desc => "Anadyr, Russia", tz => "Asia/Anadyr" },
2632             rugdx => { desc => "Magadan, Russia", tz => "Asia/Magadan" },
2633             ruikt => { desc => "Irkutsk, Russia", tz => "Asia/Irkutsk" },
2634             rukgd => { desc => "Kaliningrad, Russia", tz => "Europe/Kaliningrad" },
2635             rukhndg => { desc => "Khandyga Tomponsky, Russia", tz => "Asia/Khandyga" },
2636             rukra => { desc => "Krasnoyarsk, Russia", tz => "Asia/Krasnoyarsk" },
2637             rukuf => { desc => "Samara, Russia", tz => "Europe/Samara" },
2638             rukvx => { desc => "Kirov, Russia", tz => "Europe/Kirov" },
2639             rumow => {
2640             alias => [qw( Europe/Moscow W-SU )],
2641             desc => "Moscow, Russia",
2642             tz => "Europe/Moscow",
2643             },
2644             runoz => { desc => "Novokuznetsk, Russia", tz => "Asia/Novokuznetsk" },
2645             ruoms => { desc => "Omsk, Russia", tz => "Asia/Omsk" },
2646             ruovb => { desc => "Novosibirsk, Russia", tz => "Asia/Novosibirsk" },
2647             rupkc => { desc => "Kamchatka Peninsula, Russia", tz => "Asia/Kamchatka" },
2648             rurtw => { desc => "Saratov, Russia", tz => "Europe/Saratov" },
2649             rusred => { desc => "Srednekolymsk, Russia", tz => "Asia/Srednekolymsk" },
2650             rutof => { desc => "Tomsk, Russia", tz => "Asia/Tomsk" },
2651             ruuly => { desc => "Ulyanovsk, Russia", tz => "Europe/Ulyanovsk" },
2652             ruunera => { desc => "Ust-Nera Oymyakonsky, Russia", tz => "Asia/Ust-Nera" },
2653             ruuus => { desc => "Sakhalin, Russia", tz => "Asia/Sakhalin" },
2654             ruvog => { desc => "Volgograd, Russia", tz => "Europe/Volgograd" },
2655             ruvvo => { desc => "Vladivostok, Russia", tz => "Asia/Vladivostok" },
2656             ruyek => { desc => "Yekaterinburg, Russia", tz => "Asia/Yekaterinburg" },
2657             ruyks => { desc => "Yakutsk, Russia", tz => "Asia/Yakutsk" },
2658             rwkgl => { desc => "Kigali, Rwanda", tz => "Africa/Kigali" },
2659             saruh => { desc => "Riyadh, Saudi Arabia", tz => "Asia/Riyadh" },
2660             sbhir => { desc => "Guadalcanal, Solomon Islands", tz => "Pacific/Guadalcanal" },
2661             scmaw => { desc => "Mah\xE9, Seychelles", tz => "Indian/Mahe" },
2662             sdkrt => { desc => "Khartoum, Sudan", tz => "Africa/Khartoum" },
2663             sesto => { desc => "Stockholm, Sweden", tz => "Europe/Stockholm" },
2664             sgsin => {
2665             alias => [qw( Asia/Singapore Singapore )],
2666             desc => "Singapore",
2667             tz => "Asia/Singapore",
2668             },
2669             shshn => { desc => "Saint Helena", tz => "Atlantic/St_Helena" },
2670             silju => { desc => "Ljubljana, Slovenia", tz => "Europe/Ljubljana" },
2671             sjlyr => {
2672             alias => [qw( Arctic/Longyearbyen Atlantic/Jan_Mayen )],
2673             desc => "Longyearbyen, Svalbard",
2674             tz => "Arctic/Longyearbyen",
2675             },
2676             skbts => { desc => "Bratislava, Slovakia", tz => "Europe/Bratislava" },
2677             slfna => { desc => "Freetown, Sierra Leone", tz => "Africa/Freetown" },
2678             smsai => { desc => "San Marino", tz => "Europe/San_Marino" },
2679             sndkr => { desc => "Dakar, Senegal", tz => "Africa/Dakar" },
2680             somgq => { desc => "Mogadishu, Somalia", tz => "Africa/Mogadishu" },
2681             srpbm => { desc => "Paramaribo, Suriname", tz => "America/Paramaribo" },
2682             ssjub => { desc => "Juba, South Sudan", tz => "Africa/Juba" },
2683             sttms => {
2684             desc => "S\xE3o Tom\xE9, S\xE3o Tom\xE9 and Pr\xEDncipe",
2685             tz => "Africa/Sao_Tome",
2686             },
2687             svsal => { desc => "El Salvador", tz => "America/El_Salvador" },
2688             sxphi => { desc => "Sint Maarten", tz => "America/Lower_Princes" },
2689             sydam => { desc => "Damascus, Syria", tz => "Asia/Damascus" },
2690             szqmn => { desc => "Mbabane, Swaziland", tz => "Africa/Mbabane" },
2691             tcgdt => {
2692             desc => "Grand Turk, Turks and Caicos Islands",
2693             tz => "America/Grand_Turk",
2694             },
2695             tdndj => { desc => "N'Djamena, Chad", tz => "Africa/Ndjamena" },
2696             tfpfr => {
2697             desc => "Kerguelen Islands, French Southern Territories",
2698             tz => "Indian/Kerguelen",
2699             },
2700             tglfw => { desc => "Lom\xE9, Togo", tz => "Africa/Lome" },
2701             thbkk => { desc => "Bangkok, Thailand", tz => "Asia/Bangkok" },
2702             tjdyu => { desc => "Dushanbe, Tajikistan", tz => "Asia/Dushanbe" },
2703             tkfko => { desc => "Fakaofo, Tokelau", tz => "Pacific/Fakaofo" },
2704             tldil => { desc => "Dili, East Timor", tz => "Asia/Dili" },
2705             tmasb => {
2706             alias => [qw( Asia/Ashgabat Asia/Ashkhabad )],
2707             desc => "Ashgabat, Turkmenistan",
2708             tz => "Asia/Ashgabat",
2709             },
2710             tntun => { desc => "Tunis, Tunisia", tz => "Africa/Tunis" },
2711             totbu => { desc => "Tongatapu, Tonga", tz => "Pacific/Tongatapu" },
2712             trist => {
2713             alias => [qw( Europe/Istanbul Asia/Istanbul Turkey )],
2714             desc => "Istanbul, T\xFCrkiye",
2715             tz => "Europe/Istanbul",
2716             },
2717             ttpos => {
2718             desc => "Port of Spain, Trinidad and Tobago",
2719             tz => "America/Port_of_Spain",
2720             },
2721             tvfun => { desc => "Funafuti, Tuvalu", tz => "Pacific/Funafuti" },
2722             twtpe => {
2723             alias => [qw( Asia/Taipei ROC )],
2724             desc => "Taipei, Taiwan",
2725             tz => "Asia/Taipei",
2726             },
2727             tzdar => { desc => "Dar es Salaam, Tanzania", tz => "Africa/Dar_es_Salaam" },
2728             uaiev => {
2729             alias => [qw( Europe/Kiev Europe/Kyiv Europe/Zaporozhye Europe/Uzhgorod )],
2730             desc => "Kyiv, Ukraine",
2731             tz => "Europe/Kyiv",
2732             },
2733             uaozh => {
2734             deprecated => 1,
2735             desc => "Zaporizhia (Zaporozhye), Ukraine",
2736             preferred => "uaiev",
2737             },
2738             uasip => { desc => "Simferopol, Ukraine", tz => "Europe/Simferopol" },
2739             uauzh => {
2740             deprecated => 1,
2741             desc => "Uzhhorod (Uzhgorod), Ukraine",
2742             preferred => "uaiev",
2743             },
2744             ugkla => { desc => "Kampala, Uganda", tz => "Africa/Kampala" },
2745             umawk => {
2746             desc => "Wake Island, U.S. Minor Outlying Islands",
2747             tz => "Pacific/Wake",
2748             },
2749             umjon => {
2750             deprecated => 1,
2751             desc => "Johnston Atoll, U.S. Minor Outlying Islands",
2752             preferred => "ushnl",
2753             },
2754             ummdy => {
2755             desc => "Midway Islands, U.S. Minor Outlying Islands",
2756             tz => "Pacific/Midway",
2757             },
2758             unk => { desc => "Unknown time zone", tz => "Etc/Unknown" },
2759             usadk => {
2760             alias => [qw( America/Adak America/Atka US/Aleutian )],
2761             desc => "Adak (Alaska), United States",
2762             tz => "America/Adak",
2763             },
2764             usaeg => {
2765             desc => "Marengo (Indiana), United States",
2766             tz => "America/Indiana/Marengo",
2767             },
2768             usanc => {
2769             alias => [qw( America/Anchorage US/Alaska )],
2770             desc => "Anchorage, United States",
2771             tz => "America/Anchorage",
2772             },
2773             usboi => { desc => "Boise (Idaho), United States", tz => "America/Boise" },
2774             uschi => {
2775             alias => [qw( America/Chicago US/Central )],
2776             desc => "Chicago, United States",
2777             tz => "America/Chicago",
2778             },
2779             usden => {
2780             alias => [qw( America/Denver America/Shiprock Navajo US/Mountain )],
2781             desc => "Denver, United States",
2782             tz => "America/Denver",
2783             },
2784             usdet => {
2785             alias => [qw( America/Detroit US/Michigan )],
2786             desc => "Detroit, United States",
2787             tz => "America/Detroit",
2788             },
2789             ushnl => {
2790             alias => [qw( Pacific/Honolulu US/Hawaii Pacific/Johnston )],
2791             desc => "Honolulu, United States",
2792             tz => "Pacific/Honolulu",
2793             },
2794             usind => {
2795             alias => [qw(
2796             America/Indianapolis America/Fort_Wayne
2797             America/Indiana/Indianapolis US/East-Indiana
2798             )],
2799             desc => "Indianapolis, United States",
2800             tz => "America/Indiana/Indianapolis",
2801             },
2802             usinvev => {
2803             desc => "Vevay (Indiana), United States",
2804             tz => "America/Indiana/Vevay",
2805             },
2806             usjnu => { desc => "Juneau (Alaska), United States", tz => "America/Juneau" },
2807             usknx => {
2808             alias => [qw( America/Indiana/Knox America/Knox_IN US/Indiana-Starke )],
2809             desc => "Knox (Indiana), United States",
2810             tz => "America/Indiana/Knox",
2811             },
2812             uslax => {
2813             alias => [qw( America/Los_Angeles US/Pacific US/Pacific-New )],
2814             desc => "Los Angeles, United States",
2815             tz => "America/Los_Angeles",
2816             },
2817             uslui => {
2818             alias => [qw( America/Louisville America/Kentucky/Louisville )],
2819             desc => "Louisville (Kentucky), United States",
2820             tz => "America/Kentucky/Louisville",
2821             },
2822             usmnm => {
2823             desc => "Menominee (Michigan), United States",
2824             tz => "America/Menominee",
2825             },
2826             usmoc => {
2827             desc => "Monticello (Kentucky), United States",
2828             tz => "America/Kentucky/Monticello",
2829             },
2830             usmtm => {
2831             desc => "Metlakatla (Alaska), United States",
2832             tz => "America/Metlakatla",
2833             },
2834             usnavajo => {
2835             deprecated => 1,
2836             desc => "Shiprock (Navajo), United States",
2837             preferred => "usden",
2838             },
2839             usndcnt => {
2840             desc => "Center (North Dakota), United States",
2841             tz => "America/North_Dakota/Center",
2842             },
2843             usndnsl => {
2844             desc => "New Salem (North Dakota), United States",
2845             tz => "America/North_Dakota/New_Salem",
2846             },
2847             usnyc => {
2848             alias => [qw( America/New_York US/Eastern )],
2849             desc => "New York, United States",
2850             tz => "America/New_York",
2851             },
2852             usoea => {
2853             desc => "Vincennes (Indiana), United States",
2854             tz => "America/Indiana/Vincennes",
2855             },
2856             usome => { desc => "Nome (Alaska), United States", tz => "America/Nome" },
2857             usphx => {
2858             alias => [qw( America/Phoenix US/Arizona )],
2859             desc => "Phoenix, United States",
2860             tz => "America/Phoenix",
2861             },
2862             ussit => { desc => "Sitka (Alaska), United States", tz => "America/Sitka" },
2863             ustel => {
2864             desc => "Tell City (Indiana), United States",
2865             tz => "America/Indiana/Tell_City",
2866             },
2867             uswlz => {
2868             desc => "Winamac (Indiana), United States",
2869             tz => "America/Indiana/Winamac",
2870             },
2871             uswsq => {
2872             desc => "Petersburg (Indiana), United States",
2873             tz => "America/Indiana/Petersburg",
2874             },
2875             usxul => {
2876             desc => "Beulah (North Dakota), United States",
2877             tz => "America/North_Dakota/Beulah",
2878             },
2879             usyak => { desc => "Yakutat (Alaska), United States", tz => "America/Yakutat" },
2880             utc => {
2881             alias => [qw(
2882             Etc/UTC Etc/UCT Etc/Universal Etc/Zulu UCT UTC Universal
2883             Zulu
2884             )],
2885             desc => "UTC (Coordinated Universal Time)",
2886             tz => "Etc/UTC",
2887             },
2888             utce01 => { desc => "1 hour ahead of UTC", tz => "Etc/GMT-1" },
2889             utce02 => { desc => "2 hours ahead of UTC", tz => "Etc/GMT-2" },
2890             utce03 => { desc => "3 hours ahead of UTC", tz => "Etc/GMT-3" },
2891             utce04 => { desc => "4 hours ahead of UTC", tz => "Etc/GMT-4" },
2892             utce05 => { desc => "5 hours ahead of UTC", tz => "Etc/GMT-5" },
2893             utce06 => { desc => "6 hours ahead of UTC", tz => "Etc/GMT-6" },
2894             utce07 => { desc => "7 hours ahead of UTC", tz => "Etc/GMT-7" },
2895             utce08 => { desc => "8 hours ahead of UTC", tz => "Etc/GMT-8" },
2896             utce09 => { desc => "9 hours ahead of UTC", tz => "Etc/GMT-9" },
2897             utce10 => { desc => "10 hours ahead of UTC", tz => "Etc/GMT-10" },
2898             utce11 => { desc => "11 hours ahead of UTC", tz => "Etc/GMT-11" },
2899             utce12 => { desc => "12 hours ahead of UTC", tz => "Etc/GMT-12" },
2900             utce13 => { desc => "13 hours ahead of UTC", tz => "Etc/GMT-13" },
2901             utce14 => { desc => "14 hours ahead of UTC", tz => "Etc/GMT-14" },
2902             utcw01 => { desc => "1 hour behind UTC", tz => "Etc/GMT+1" },
2903             utcw02 => { desc => "2 hours behind UTC", tz => "Etc/GMT+2" },
2904             utcw03 => { desc => "3 hours behind UTC", tz => "Etc/GMT+3" },
2905             utcw04 => { desc => "4 hours behind UTC", tz => "Etc/GMT+4" },
2906             utcw05 => {
2907             alias => [qw( Etc/GMT+5 EST )],
2908             desc => "5 hours behind UTC",
2909             tz => "Etc/GMT+5",
2910             },
2911             utcw06 => { desc => "6 hours behind UTC", tz => "Etc/GMT+6" },
2912             utcw07 => {
2913             alias => [qw( Etc/GMT+7 MST )],
2914             desc => "7 hours behind UTC",
2915             tz => "Etc/GMT+7",
2916             },
2917             utcw08 => { desc => "8 hours behind UTC", tz => "Etc/GMT+8" },
2918             utcw09 => { desc => "9 hours behind UTC", tz => "Etc/GMT+9" },
2919             utcw10 => {
2920             alias => [qw( Etc/GMT+10 HST )],
2921             desc => "10 hours behind UTC",
2922             tz => "Etc/GMT+10",
2923             },
2924             utcw11 => { desc => "11 hours behind UTC", tz => "Etc/GMT+11" },
2925             utcw12 => { desc => "12 hours behind UTC", tz => "Etc/GMT+12" },
2926             uymvd => { desc => "Montevideo, Uruguay", tz => "America/Montevideo" },
2927             uzskd => { desc => "Samarkand, Uzbekistan", tz => "Asia/Samarkand" },
2928             uztas => { desc => "Tashkent, Uzbekistan", tz => "Asia/Tashkent" },
2929             vavat => { desc => "Vatican City", tz => "Europe/Vatican" },
2930             vcsvd => {
2931             desc => "Saint Vincent, Saint Vincent and the Grenadines",
2932             tz => "America/St_Vincent",
2933             },
2934             veccs => { desc => "Caracas, Venezuela", tz => "America/Caracas" },
2935             vgtov => { desc => "Tortola, British Virgin Islands", tz => "America/Tortola" },
2936             vistt => {
2937             alias => [qw( America/St_Thomas America/Virgin )],
2938             desc => "Saint Thomas, U.S. Virgin Islands",
2939             tz => "America/St_Thomas",
2940             },
2941             vnsgn => {
2942             alias => [qw( Asia/Saigon Asia/Ho_Chi_Minh )],
2943             desc => "Ho Chi Minh City, Vietnam",
2944             tz => "Asia/Ho_Chi_Minh",
2945             },
2946             vuvli => { desc => "Efate, Vanuatu", tz => "Pacific/Efate" },
2947             wfmau => { desc => "Wallis Islands, Wallis and Futuna", tz => "Pacific/Wallis" },
2948             wsapw => { desc => "Apia, Samoa", tz => "Pacific/Apia" },
2949             yeade => { desc => "Aden, Yemen", tz => "Asia/Aden" },
2950             ytmam => { desc => "Mayotte", tz => "Indian/Mayotte" },
2951             zajnb => { desc => "Johannesburg, South Africa", tz => "Africa/Johannesburg" },
2952             zmlun => { desc => "Lusaka, Zambia", tz => "Africa/Lusaka" },
2953             zwhre => { desc => "Harare, Zimbabwe", tz => "Africa/Harare" },
2954             };
2955              
2956             # NOTE: $TZ_NAME2ID
2957             # This BCP47 timezone database is different from the Olson IANA database in that it keeps old record for reliability and consistency.
2958             # See <https://github.com/unicode-org/cldr/blob/main/common/bcp47/timezone.xml>
2959             # <https://www.iana.org/time-zones>
2960             # <ftp://ftp.iana.org/tz/releases/>
2961             $TZ_NAME2ID =
2962             {
2963             "Africa/Abidjan" => "ciabj",
2964             "Africa/Accra" => "ghacc",
2965             "Africa/Addis_Ababa" => "etadd",
2966             "Africa/Algiers" => "dzalg",
2967             "Africa/Asmara" => "erasm",
2968             "Africa/Asmera" => "erasm",
2969             "Africa/Bamako" => "mlbko",
2970             "Africa/Bangui" => "cfbgf",
2971             "Africa/Banjul" => "gmbjl",
2972             "Africa/Bissau" => "gwoxb",
2973             "Africa/Blantyre" => "mwblz",
2974             "Africa/Brazzaville" => "cgbzv",
2975             "Africa/Bujumbura" => "bibjm",
2976             "Africa/Cairo" => "egcai",
2977             "Africa/Casablanca" => "macas",
2978             "Africa/Ceuta" => "esceu",
2979             "Africa/Conakry" => "gncky",
2980             "Africa/Dakar" => "sndkr",
2981             "Africa/Dar_es_Salaam" => "tzdar",
2982             "Africa/Djibouti" => "djjib",
2983             "Africa/Douala" => "cmdla",
2984             "Africa/El_Aaiun" => "eheai",
2985             "Africa/Freetown" => "slfna",
2986             "Africa/Gaborone" => "bwgbe",
2987             "Africa/Harare" => "zwhre",
2988             "Africa/Johannesburg" => "zajnb",
2989             "Africa/Juba" => "ssjub",
2990             "Africa/Kampala" => "ugkla",
2991             "Africa/Khartoum" => "sdkrt",
2992             "Africa/Kigali" => "rwkgl",
2993             "Africa/Kinshasa" => "cdfih",
2994             "Africa/Lagos" => "nglos",
2995             "Africa/Libreville" => "galbv",
2996             "Africa/Lome" => "tglfw",
2997             "Africa/Luanda" => "aolad",
2998             "Africa/Lubumbashi" => "cdfbm",
2999             "Africa/Lusaka" => "zmlun",
3000             "Africa/Malabo" => "gqssg",
3001             "Africa/Maputo" => "mzmpm",
3002             "Africa/Maseru" => "lsmsu",
3003             "Africa/Mbabane" => "szqmn",
3004             "Africa/Mogadishu" => "somgq",
3005             "Africa/Monrovia" => "lrmlw",
3006             "Africa/Nairobi" => "kenbo",
3007             "Africa/Ndjamena" => "tdndj",
3008             "Africa/Niamey" => "nenim",
3009             "Africa/Nouakchott" => "mrnkc",
3010             "Africa/Ouagadougou" => "bfoua",
3011             "Africa/Porto-Novo" => "bjptn",
3012             "Africa/Sao_Tome" => "sttms",
3013             "Africa/Timbuktu" => "mlbko",
3014             "Africa/Tripoli" => "lytip",
3015             "Africa/Tunis" => "tntun",
3016             "Africa/Windhoek" => "nawdh",
3017             "America/Adak" => "usadk",
3018             "America/Anchorage" => "usanc",
3019             "America/Anguilla" => "aiaxa",
3020             "America/Antigua" => "aganu",
3021             "America/Araguaina" => "braux",
3022             "America/Argentina/Buenos_Aires" => "arbue",
3023             "America/Argentina/Catamarca" => "arctc",
3024             "America/Argentina/ComodRivadavia" => "arctc",
3025             "America/Argentina/Cordoba" => "arcor",
3026             "America/Argentina/Jujuy" => "arjuj",
3027             "America/Argentina/La_Rioja" => "arirj",
3028             "America/Argentina/Mendoza" => "armdz",
3029             "America/Argentina/Rio_Gallegos" => "arrgl",
3030             "America/Argentina/Salta" => "arsla",
3031             "America/Argentina/San_Juan" => "aruaq",
3032             "America/Argentina/San_Luis" => "arluq",
3033             "America/Argentina/Tucuman" => "artuc",
3034             "America/Argentina/Ushuaia" => "arush",
3035             "America/Aruba" => "awaua",
3036             "America/Asuncion" => "pyasu",
3037             "America/Atikokan" => "cayzs",
3038             "America/Atka" => "usadk",
3039             "America/Bahia" => "brssa",
3040             "America/Bahia_Banderas" => "mxpvr",
3041             "America/Barbados" => "bbbgi",
3042             "America/Belem" => "brbel",
3043             "America/Belize" => "bzbze",
3044             "America/Blanc-Sablon" => "caybx",
3045             "America/Boa_Vista" => "brbvb",
3046             "America/Bogota" => "cobog",
3047             "America/Boise" => "usboi",
3048             "America/Buenos_Aires" => "arbue",
3049             "America/Cambridge_Bay" => "caycb",
3050             "America/Campo_Grande" => "brcgr",
3051             "America/Cancun" => "mxcun",
3052             "America/Caracas" => "veccs",
3053             "America/Catamarca" => "arctc",
3054             "America/Cayenne" => "gfcay",
3055             "America/Cayman" => "kygec",
3056             "America/Chicago" => "uschi",
3057             "America/Chihuahua" => "mxchi",
3058             "America/Ciudad_Juarez" => "mxcjs",
3059             "America/Coral_Harbour" => "cayzs",
3060             "America/Cordoba" => "arcor",
3061             "America/Costa_Rica" => "crsjo",
3062             "America/Creston" => "cacfq",
3063             "America/Cuiaba" => "brcgb",
3064             "America/Curacao" => "ancur",
3065             "America/Danmarkshavn" => "gldkshvn",
3066             "America/Dawson" => "cayda",
3067             "America/Dawson_Creek" => "caydq",
3068             "America/Denver" => "usden",
3069             "America/Detroit" => "usdet",
3070             "America/Dominica" => "dmdom",
3071             "America/Edmonton" => "caedm",
3072             "America/Eirunepe" => "brern",
3073             "America/El_Salvador" => "svsal",
3074             "America/Ensenada" => "mxtij",
3075             "America/Fort_Nelson" => "cafne",
3076             "America/Fort_Wayne" => "usind",
3077             "America/Fortaleza" => "brfor",
3078             "America/Glace_Bay" => "caglb",
3079             "America/Godthab" => "glgoh",
3080             "America/Goose_Bay" => "cagoo",
3081             "America/Grand_Turk" => "tcgdt",
3082             "America/Grenada" => "gdgnd",
3083             "America/Guadeloupe" => "gpbbr",
3084             "America/Guatemala" => "gtgua",
3085             "America/Guayaquil" => "ecgye",
3086             "America/Guyana" => "gygeo",
3087             "America/Halifax" => "cahal",
3088             "America/Havana" => "cuhav",
3089             "America/Hermosillo" => "mxhmo",
3090             "America/Indiana/Indianapolis" => "usind",
3091             "America/Indiana/Knox" => "usknx",
3092             "America/Indiana/Marengo" => "usaeg",
3093             "America/Indiana/Petersburg" => "uswsq",
3094             "America/Indiana/Tell_City" => "ustel",
3095             "America/Indiana/Vevay" => "usinvev",
3096             "America/Indiana/Vincennes" => "usoea",
3097             "America/Indiana/Winamac" => "uswlz",
3098             "America/Indianapolis" => "usind",
3099             "America/Inuvik" => "cayev",
3100             "America/Iqaluit" => "caiql",
3101             "America/Jamaica" => "jmkin",
3102             "America/Jujuy" => "arjuj",
3103             "America/Juneau" => "usjnu",
3104             "America/Kentucky/Louisville" => "uslui",
3105             "America/Kentucky/Monticello" => "usmoc",
3106             "America/Knox_IN" => "usknx",
3107             "America/Kralendijk" => "bqkra",
3108             "America/La_Paz" => "bolpb",
3109             "America/Lima" => "pelim",
3110             "America/Los_Angeles" => "uslax",
3111             "America/Louisville" => "uslui",
3112             "America/Lower_Princes" => "sxphi",
3113             "America/Maceio" => "brmcz",
3114             "America/Managua" => "nimga",
3115             "America/Manaus" => "brmao",
3116             "America/Marigot" => "gpmsb",
3117             "America/Martinique" => "mqfdf",
3118             "America/Matamoros" => "mxmam",
3119             "America/Mazatlan" => "mxmzt",
3120             "America/Mendoza" => "armdz",
3121             "America/Menominee" => "usmnm",
3122             "America/Merida" => "mxmid",
3123             "America/Metlakatla" => "usmtm",
3124             "America/Mexico_City" => "mxmex",
3125             "America/Miquelon" => "pmmqc",
3126             "America/Moncton" => "camon",
3127             "America/Monterrey" => "mxmty",
3128             "America/Montevideo" => "uymvd",
3129             "America/Montreal" => "cator",
3130             "America/Montserrat" => "msmni",
3131             "America/Nassau" => "bsnas",
3132             "America/New_York" => "usnyc",
3133             "America/Nipigon" => "cator",
3134             "America/Nome" => "usome",
3135             "America/Noronha" => "brfen",
3136             "America/North_Dakota/Beulah" => "usxul",
3137             "America/North_Dakota/Center" => "usndcnt",
3138             "America/North_Dakota/New_Salem" => "usndnsl",
3139             "America/Nuuk" => "glgoh",
3140             "America/Ojinaga" => "mxoji",
3141             "America/Panama" => "papty",
3142             "America/Pangnirtung" => "caiql",
3143             "America/Paramaribo" => "srpbm",
3144             "America/Phoenix" => "usphx",
3145             "America/Port-au-Prince" => "htpap",
3146             "America/Port_of_Spain" => "ttpos",
3147             "America/Porto_Acre" => "brrbr",
3148             "America/Porto_Velho" => "brpvh",
3149             "America/Puerto_Rico" => "prsju",
3150             "America/Punta_Arenas" => "clpuq",
3151             "America/Rainy_River" => "cawnp",
3152             "America/Rankin_Inlet" => "cayek",
3153             "America/Recife" => "brrec",
3154             "America/Regina" => "careg",
3155             "America/Resolute" => "careb",
3156             "America/Rio_Branco" => "brrbr",
3157             "America/Rosario" => "arcor",
3158             "America/Santa_Isabel" => "mxtij",
3159             "America/Santarem" => "brstm",
3160             "America/Santiago" => "clscl",
3161             "America/Santo_Domingo" => "dosdq",
3162             "America/Sao_Paulo" => "brsao",
3163             "America/Scoresbysund" => "globy",
3164             "America/Shiprock" => "usden",
3165             "America/Sitka" => "ussit",
3166             "America/St_Barthelemy" => "gpsbh",
3167             "America/St_Johns" => "casjf",
3168             "America/St_Kitts" => "knbas",
3169             "America/St_Lucia" => "lccas",
3170             "America/St_Thomas" => "vistt",
3171             "America/St_Vincent" => "vcsvd",
3172             "America/Swift_Current" => "cayyn",
3173             "America/Tegucigalpa" => "hntgu",
3174             "America/Thule" => "glthu",
3175             "America/Thunder_Bay" => "cator",
3176             "America/Tijuana" => "mxtij",
3177             "America/Toronto" => "cator",
3178             "America/Tortola" => "vgtov",
3179             "America/Vancouver" => "cavan",
3180             "America/Virgin" => "vistt",
3181             "America/Whitehorse" => "cayxy",
3182             "America/Winnipeg" => "cawnp",
3183             "America/Yakutat" => "usyak",
3184             "America/Yellowknife" => "caedm",
3185             "Antarctica/Casey" => "aqcas",
3186             "Antarctica/Davis" => "aqdav",
3187             "Antarctica/DumontDUrville" => "aqddu",
3188             "Antarctica/Macquarie" => "aumqi",
3189             "Antarctica/Mawson" => "aqmaw",
3190             "Antarctica/McMurdo" => "aqmcm",
3191             "Antarctica/Palmer" => "aqplm",
3192             "Antarctica/Rothera" => "aqrot",
3193             "Antarctica/South_Pole" => "nzakl",
3194             "Antarctica/Syowa" => "aqsyw",
3195             "Antarctica/Troll" => "aqtrl",
3196             "Antarctica/Vostok" => "aqvos",
3197             "Arctic/Longyearbyen" => "sjlyr",
3198             "Asia/Aden" => "yeade",
3199             "Asia/Almaty" => "kzala",
3200             "Asia/Amman" => "joamm",
3201             "Asia/Anadyr" => "rudyr",
3202             "Asia/Aqtau" => "kzaau",
3203             "Asia/Aqtobe" => "kzakx",
3204             "Asia/Ashgabat" => "tmasb",
3205             "Asia/Ashkhabad" => "tmasb",
3206             "Asia/Atyrau" => "kzguw",
3207             "Asia/Baghdad" => "iqbgw",
3208             "Asia/Bahrain" => "bhbah",
3209             "Asia/Baku" => "azbak",
3210             "Asia/Bangkok" => "thbkk",
3211             "Asia/Barnaul" => "rubax",
3212             "Asia/Beirut" => "lbbey",
3213             "Asia/Bishkek" => "kgfru",
3214             "Asia/Brunei" => "bnbwn",
3215             "Asia/Calcutta" => "inccu",
3216             "Asia/Chita" => "ruchita",
3217             "Asia/Choibalsan" => "mncoq",
3218             "Asia/Chongqing" => "cnsha",
3219             "Asia/Chungking" => "cnsha",
3220             "Asia/Colombo" => "lkcmb",
3221             "Asia/Dacca" => "bddac",
3222             "Asia/Damascus" => "sydam",
3223             "Asia/Dhaka" => "bddac",
3224             "Asia/Dili" => "tldil",
3225             "Asia/Dubai" => "aedxb",
3226             "Asia/Dushanbe" => "tjdyu",
3227             "Asia/Famagusta" => "cyfmg",
3228             "Asia/Gaza" => "gazastrp",
3229             "Asia/Harbin" => "cnsha",
3230             "Asia/Hebron" => "hebron",
3231             "Asia/Ho_Chi_Minh" => "vnsgn",
3232             "Asia/Hong_Kong" => "hkhkg",
3233             "Asia/Hovd" => "mnhvd",
3234             "Asia/Irkutsk" => "ruikt",
3235             "Asia/Istanbul" => "trist",
3236             "Asia/Jakarta" => "idjkt",
3237             "Asia/Jayapura" => "iddjj",
3238             "Asia/Jerusalem" => "jeruslm",
3239             "Asia/Kabul" => "afkbl",
3240             "Asia/Kamchatka" => "rupkc",
3241             "Asia/Karachi" => "pkkhi",
3242             "Asia/Kashgar" => "cnurc",
3243             "Asia/Kathmandu" => "npktm",
3244             "Asia/Katmandu" => "npktm",
3245             "Asia/Khandyga" => "rukhndg",
3246             "Asia/Kolkata" => "inccu",
3247             "Asia/Krasnoyarsk" => "rukra",
3248             "Asia/Kuala_Lumpur" => "mykul",
3249             "Asia/Kuching" => "mykch",
3250             "Asia/Kuwait" => "kwkwi",
3251             "Asia/Macao" => "momfm",
3252             "Asia/Macau" => "momfm",
3253             "Asia/Magadan" => "rugdx",
3254             "Asia/Makassar" => "idmak",
3255             "Asia/Manila" => "phmnl",
3256             "Asia/Muscat" => "ommct",
3257             "Asia/Nicosia" => "cynic",
3258             "Asia/Novokuznetsk" => "runoz",
3259             "Asia/Novosibirsk" => "ruovb",
3260             "Asia/Omsk" => "ruoms",
3261             "Asia/Oral" => "kzura",
3262             "Asia/Phnom_Penh" => "khpnh",
3263             "Asia/Pontianak" => "idpnk",
3264             "Asia/Pyongyang" => "kpfnj",
3265             "Asia/Qatar" => "qadoh",
3266             "Asia/Qostanay" => "kzksn",
3267             "Asia/Qyzylorda" => "kzkzo",
3268             "Asia/Rangoon" => "mmrgn",
3269             "Asia/Riyadh" => "saruh",
3270             "Asia/Saigon" => "vnsgn",
3271             "Asia/Sakhalin" => "ruuus",
3272             "Asia/Samarkand" => "uzskd",
3273             "Asia/Seoul" => "krsel",
3274             "Asia/Shanghai" => "cnsha",
3275             "Asia/Singapore" => "sgsin",
3276             "Asia/Srednekolymsk" => "rusred",
3277             "Asia/Taipei" => "twtpe",
3278             "Asia/Tashkent" => "uztas",
3279             "Asia/Tbilisi" => "getbs",
3280             "Asia/Tehran" => "irthr",
3281             "Asia/Tel_Aviv" => "jeruslm",
3282             "Asia/Thimbu" => "btthi",
3283             "Asia/Thimphu" => "btthi",
3284             "Asia/Tokyo" => "jptyo",
3285             "Asia/Tomsk" => "rutof",
3286             "Asia/Ujung_Pandang" => "idmak",
3287             "Asia/Ulaanbaatar" => "mnuln",
3288             "Asia/Ulan_Bator" => "mnuln",
3289             "Asia/Urumqi" => "cnurc",
3290             "Asia/Ust-Nera" => "ruunera",
3291             "Asia/Vientiane" => "lavte",
3292             "Asia/Vladivostok" => "ruvvo",
3293             "Asia/Yakutsk" => "ruyks",
3294             "Asia/Yangon" => "mmrgn",
3295             "Asia/Yekaterinburg" => "ruyek",
3296             "Asia/Yerevan" => "amevn",
3297             "Atlantic/Azores" => "ptpdl",
3298             "Atlantic/Bermuda" => "bmbda",
3299             "Atlantic/Canary" => "eslpa",
3300             "Atlantic/Cape_Verde" => "cvrai",
3301             "Atlantic/Faeroe" => "fotho",
3302             "Atlantic/Faroe" => "fotho",
3303             "Atlantic/Jan_Mayen" => "sjlyr",
3304             "Atlantic/Madeira" => "ptfnc",
3305             "Atlantic/Reykjavik" => "isrey",
3306             "Atlantic/South_Georgia" => "gsgrv",
3307             "Atlantic/St_Helena" => "shshn",
3308             "Atlantic/Stanley" => "fkpsy",
3309             "Australia/ACT" => "ausyd",
3310             "Australia/Adelaide" => "auadl",
3311             "Australia/Brisbane" => "aubne",
3312             "Australia/Broken_Hill" => "aubhq",
3313             "Australia/Canberra" => "ausyd",
3314             "Australia/Currie" => "auhba",
3315             "Australia/Darwin" => "audrw",
3316             "Australia/Eucla" => "aueuc",
3317             "Australia/Hobart" => "auhba",
3318             "Australia/LHI" => "auldh",
3319             "Australia/Lindeman" => "auldc",
3320             "Australia/Lord_Howe" => "auldh",
3321             "Australia/Melbourne" => "aumel",
3322             "Australia/North" => "audrw",
3323             "Australia/NSW" => "ausyd",
3324             "Australia/Perth" => "auper",
3325             "Australia/Queensland" => "aubne",
3326             "Australia/South" => "auadl",
3327             "Australia/Sydney" => "ausyd",
3328             "Australia/Tasmania" => "auhba",
3329             "Australia/Victoria" => "aumel",
3330             "Australia/West" => "auper",
3331             "Australia/Yancowinna" => "aubhq",
3332             "Brazil/Acre" => "brrbr",
3333             "Brazil/DeNoronha" => "brfen",
3334             "Brazil/East" => "brsao",
3335             "Brazil/West" => "brmao",
3336             "Canada/Atlantic" => "cahal",
3337             "Canada/Central" => "cawnp",
3338             "Canada/East-Saskatchewan" => "careg",
3339             "Canada/Eastern" => "cator",
3340             "Canada/Mountain" => "caedm",
3341             "Canada/Newfoundland" => "casjf",
3342             "Canada/Pacific" => "cavan",
3343             "Canada/Saskatchewan" => "careg",
3344             "Canada/Yukon" => "cayxy",
3345             "Chile/Continental" => "clscl",
3346             "Chile/EasterIsland" => "clipc",
3347             CST6CDT => "cst6cdt",
3348             Cuba => "cuhav",
3349             Egypt => "egcai",
3350             Eire => "iedub",
3351             EST => "utcw05",
3352             EST5EDT => "est5edt",
3353             "Etc/GMT" => "gmt",
3354             "Etc/GMT+0" => "gmt",
3355             "Etc/GMT+1" => "utcw01",
3356             "Etc/GMT+10" => "utcw10",
3357             "Etc/GMT+11" => "utcw11",
3358             "Etc/GMT+12" => "utcw12",
3359             "Etc/GMT+2" => "utcw02",
3360             "Etc/GMT+3" => "utcw03",
3361             "Etc/GMT+4" => "utcw04",
3362             "Etc/GMT+5" => "utcw05",
3363             "Etc/GMT+6" => "utcw06",
3364             "Etc/GMT+7" => "utcw07",
3365             "Etc/GMT+8" => "utcw08",
3366             "Etc/GMT+9" => "utcw09",
3367             "Etc/GMT-0" => "gmt",
3368             "Etc/GMT-1" => "utce01",
3369             "Etc/GMT-10" => "utce10",
3370             "Etc/GMT-11" => "utce11",
3371             "Etc/GMT-12" => "utce12",
3372             "Etc/GMT-13" => "utce13",
3373             "Etc/GMT-14" => "utce14",
3374             "Etc/GMT-2" => "utce02",
3375             "Etc/GMT-3" => "utce03",
3376             "Etc/GMT-4" => "utce04",
3377             "Etc/GMT-5" => "utce05",
3378             "Etc/GMT-6" => "utce06",
3379             "Etc/GMT-7" => "utce07",
3380             "Etc/GMT-8" => "utce08",
3381             "Etc/GMT-9" => "utce09",
3382             "Etc/GMT0" => "gmt",
3383             "Etc/Greenwich" => "gmt",
3384             "Etc/UCT" => "utc",
3385             "Etc/Universal" => "utc",
3386             "Etc/Unknown" => "unk",
3387             "Etc/UTC" => "utc",
3388             "Etc/Zulu" => "utc",
3389             "Europe/Amsterdam" => "nlams",
3390             "Europe/Andorra" => "adalv",
3391             "Europe/Astrakhan" => "ruasf",
3392             "Europe/Athens" => "grath",
3393             "Europe/Belfast" => "gblon",
3394             "Europe/Belgrade" => "rsbeg",
3395             "Europe/Berlin" => "deber",
3396             "Europe/Bratislava" => "skbts",
3397             "Europe/Brussels" => "bebru",
3398             "Europe/Bucharest" => "robuh",
3399             "Europe/Budapest" => "hubud",
3400             "Europe/Busingen" => "debsngn",
3401             "Europe/Chisinau" => "mdkiv",
3402             "Europe/Copenhagen" => "dkcph",
3403             "Europe/Dublin" => "iedub",
3404             "Europe/Gibraltar" => "gigib",
3405             "Europe/Guernsey" => "gggci",
3406             "Europe/Helsinki" => "fihel",
3407             "Europe/Isle_of_Man" => "imdgs",
3408             "Europe/Istanbul" => "trist",
3409             "Europe/Jersey" => "jesth",
3410             "Europe/Kaliningrad" => "rukgd",
3411             "Europe/Kiev" => "uaiev",
3412             "Europe/Kirov" => "rukvx",
3413             "Europe/Kyiv" => "uaiev",
3414             "Europe/Lisbon" => "ptlis",
3415             "Europe/Ljubljana" => "silju",
3416             "Europe/London" => "gblon",
3417             "Europe/Luxembourg" => "lulux",
3418             "Europe/Madrid" => "esmad",
3419             "Europe/Malta" => "mtmla",
3420             "Europe/Mariehamn" => "fimhq",
3421             "Europe/Minsk" => "bymsq",
3422             "Europe/Monaco" => "mcmon",
3423             "Europe/Moscow" => "rumow",
3424             "Europe/Nicosia" => "cynic",
3425             "Europe/Oslo" => "noosl",
3426             "Europe/Paris" => "frpar",
3427             "Europe/Podgorica" => "metgd",
3428             "Europe/Prague" => "czprg",
3429             "Europe/Riga" => "lvrix",
3430             "Europe/Rome" => "itrom",
3431             "Europe/Samara" => "rukuf",
3432             "Europe/San_Marino" => "smsai",
3433             "Europe/Sarajevo" => "basjj",
3434             "Europe/Saratov" => "rurtw",
3435             "Europe/Simferopol" => "uasip",
3436             "Europe/Skopje" => "mkskp",
3437             "Europe/Sofia" => "bgsof",
3438             "Europe/Stockholm" => "sesto",
3439             "Europe/Tallinn" => "eetll",
3440             "Europe/Tirane" => "altia",
3441             "Europe/Tiraspol" => "mdkiv",
3442             "Europe/Ulyanovsk" => "ruuly",
3443             "Europe/Uzhgorod" => "uaiev",
3444             "Europe/Vaduz" => "livdz",
3445             "Europe/Vatican" => "vavat",
3446             "Europe/Vienna" => "atvie",
3447             "Europe/Vilnius" => "ltvno",
3448             "Europe/Volgograd" => "ruvog",
3449             "Europe/Warsaw" => "plwaw",
3450             "Europe/Zagreb" => "hrzag",
3451             "Europe/Zaporozhye" => "uaiev",
3452             "Europe/Zurich" => "chzrh",
3453             GB => "gblon",
3454             "GB-Eire" => "gblon",
3455             GMT => "gmt",
3456             "GMT+0" => "gmt",
3457             "GMT-0" => "gmt",
3458             GMT0 => "gmt",
3459             Greenwich => "gmt",
3460             Hongkong => "hkhkg",
3461             HST => "utcw10",
3462             Iceland => "isrey",
3463             "Indian/Antananarivo" => "mgtnr",
3464             "Indian/Chagos" => "iodga",
3465             "Indian/Christmas" => "cxxch",
3466             "Indian/Cocos" => "cccck",
3467             "Indian/Comoro" => "kmyva",
3468             "Indian/Kerguelen" => "tfpfr",
3469             "Indian/Mahe" => "scmaw",
3470             "Indian/Maldives" => "mvmle",
3471             "Indian/Mauritius" => "muplu",
3472             "Indian/Mayotte" => "ytmam",
3473             "Indian/Reunion" => "rereu",
3474             Iran => "irthr",
3475             Israel => "jeruslm",
3476             Jamaica => "jmkin",
3477             Japan => "jptyo",
3478             Kwajalein => "mhkwa",
3479             Libya => "lytip",
3480             "Mexico/BajaNorte" => "mxtij",
3481             "Mexico/BajaSur" => "mxmzt",
3482             "Mexico/General" => "mxmex",
3483             MST => "utcw07",
3484             MST7MDT => "mst7mdt",
3485             Navajo => "usden",
3486             NZ => "nzakl",
3487             "NZ-CHAT" => "nzcht",
3488             "Pacific/Apia" => "wsapw",
3489             "Pacific/Auckland" => "nzakl",
3490             "Pacific/Bougainville" => "pgraw",
3491             "Pacific/Chatham" => "nzcht",
3492             "Pacific/Chuuk" => "fmtkk",
3493             "Pacific/Easter" => "clipc",
3494             "Pacific/Efate" => "vuvli",
3495             "Pacific/Enderbury" => "kipho",
3496             "Pacific/Fakaofo" => "tkfko",
3497             "Pacific/Fiji" => "fjsuv",
3498             "Pacific/Funafuti" => "tvfun",
3499             "Pacific/Galapagos" => "ecgps",
3500             "Pacific/Gambier" => "pfgmr",
3501             "Pacific/Guadalcanal" => "sbhir",
3502             "Pacific/Guam" => "gugum",
3503             "Pacific/Honolulu" => "ushnl",
3504             "Pacific/Johnston" => "ushnl",
3505             "Pacific/Kanton" => "kipho",
3506             "Pacific/Kiritimati" => "kicxi",
3507             "Pacific/Kosrae" => "fmksa",
3508             "Pacific/Kwajalein" => "mhkwa",
3509             "Pacific/Majuro" => "mhmaj",
3510             "Pacific/Marquesas" => "pfnhv",
3511             "Pacific/Midway" => "ummdy",
3512             "Pacific/Nauru" => "nrinu",
3513             "Pacific/Niue" => "nuiue",
3514             "Pacific/Norfolk" => "nfnlk",
3515             "Pacific/Noumea" => "ncnou",
3516             "Pacific/Pago_Pago" => "asppg",
3517             "Pacific/Palau" => "pwror",
3518             "Pacific/Pitcairn" => "pnpcn",
3519             "Pacific/Pohnpei" => "fmpni",
3520             "Pacific/Ponape" => "fmpni",
3521             "Pacific/Port_Moresby" => "pgpom",
3522             "Pacific/Rarotonga" => "ckrar",
3523             "Pacific/Saipan" => "mpspn",
3524             "Pacific/Samoa" => "asppg",
3525             "Pacific/Tahiti" => "pfppt",
3526             "Pacific/Tarawa" => "kitrw",
3527             "Pacific/Tongatapu" => "totbu",
3528             "Pacific/Truk" => "fmtkk",
3529             "Pacific/Wake" => "umawk",
3530             "Pacific/Wallis" => "wfmau",
3531             "Pacific/Yap" => "fmtkk",
3532             Poland => "plwaw",
3533             Portugal => "ptlis",
3534             PRC => "cnsha",
3535             PST8PDT => "pst8pdt",
3536             ROC => "twtpe",
3537             ROK => "krsel",
3538             Singapore => "sgsin",
3539             Turkey => "trist",
3540             UCT => "utc",
3541             Universal => "utc",
3542             "US/Alaska" => "usanc",
3543             "US/Aleutian" => "usadk",
3544             "US/Arizona" => "usphx",
3545             "US/Central" => "uschi",
3546             "US/East-Indiana" => "usind",
3547             "US/Eastern" => "usnyc",
3548             "US/Hawaii" => "ushnl",
3549             "US/Indiana-Starke" => "usknx",
3550             "US/Michigan" => "usdet",
3551             "US/Mountain" => "usden",
3552             "US/Pacific" => "uslax",
3553             "US/Pacific-New" => "uslax",
3554             "US/Samoa" => "asppg",
3555             UTC => "utc",
3556             "W-SU" => "rumow",
3557             Zulu => "utc",
3558             };
3559             };
3560              
3561             sub FREEZE
3562             {
3563 0     0 0 0 my $self = CORE::shift( @_ );
3564 0   0     0 my $serialiser = CORE::shift( @_ ) // '';
3565 0         0 my $class = CORE::ref( $self );
3566 0         0 my %hash = %$self;
3567             # Return an array reference rather than a list so this works with Sereal and CBOR
3568             # On or before Sereal version 4.023, Sereal did not support multiple values returned
3569 0 0 0     0 CORE::return( [$class, \%hash] ) if( $serialiser eq 'Sereal' && Sereal::Encoder->VERSION <= version->parse( '4.023' ) );
3570             # But Storable want a list with the first element being the serialised element
3571 0         0 CORE::return( $class, \%hash );
3572             }
3573              
3574 0     0 0 0 sub STORABLE_freeze { return( shift->FREEZE( @_ ) ); }
3575              
3576 0     0 0 0 sub STORABLE_thaw { return( shift->THAW( @_ ) ); }
3577              
3578             # NOTE: CBOR will call the THAW method with the stored classname as first argument, the constant string CBOR as second argument, and all values returned by FREEZE as remaining arguments.
3579             # NOTE: Storable calls it with a blessed object it created followed with $cloning and any other arguments initially provided by STORABLE_freeze
3580             sub THAW
3581             {
3582 0     0 0 0 my( $self, undef, @args ) = @_;
3583 0 0 0     0 my $ref = ( CORE::scalar( @args ) == 1 && CORE::ref( $args[0] ) eq 'ARRAY' ) ? CORE::shift( @args ) : \@args;
3584 0 0 0     0 my $class = ( CORE::defined( $ref ) && CORE::ref( $ref ) eq 'ARRAY' && CORE::scalar( @$ref ) > 1 ) ? CORE::shift( @$ref ) : ( CORE::ref( $self ) || $self );
      0        
3585 0 0       0 my $hash = CORE::ref( $ref ) eq 'ARRAY' ? CORE::shift( @$ref ) : {};
3586 0         0 my $new;
3587             # Storable pattern requires to modify the object it created rather than returning a new one
3588 0 0       0 if( CORE::ref( $self ) )
3589             {
3590 0         0 foreach( CORE::keys( %$hash ) )
3591             {
3592 0         0 $self->{ $_ } = CORE::delete( $hash->{ $_ } );
3593             }
3594 0         0 $new = $self;
3595             }
3596             else
3597             {
3598 0         0 $new = CORE::bless( $hash => $class );
3599             }
3600 0         0 CORE::return( $new );
3601             }
3602              
3603 0     0 0 0 sub TO_JSON { return( shift->as_string ); }
3604              
3605             # NOTE: Locale::Unicode::Boolean class
3606             package Locale::Unicode::Boolean;
3607             BEGIN
3608             {
3609 3     3   29 use strict;
  3         6  
  3         149  
3610 3     3   14 use warnings;
  3         6  
  3         215  
3611 3     3   17 use vars qw( $VERSION $true $false );
  3         3  
  3         491  
3612             use overload
3613 0     0   0 "0+" => sub{ ${$_[0]} },
  0         0  
3614 0     0   0 "++" => sub{ $_[0] = ${$_[0]} + 1 },
  0         0  
3615 0     0   0 "--" => sub{ $_[0] = ${$_[0]} - 1 },
  0         0  
3616 3     3   17 fallback => 1;
  3         5  
  3         90  
3617 3     3   528 $true = do{ bless( \( my $dummy = 1 ) => 'Locale::Unicode::Boolean' ) };
  3         13  
3618 3         6 $false = do{ bless( \( my $dummy = 0 ) => 'Locale::Unicode::Boolean' ) };
  3         30  
3619 3         95 our $VERSION = 'v0.1.0';
3620             };
3621 3     3   20 use strict;
  3         7  
  3         101  
3622 3     3   13 use warnings;
  3         7  
  3         2110  
3623              
3624             sub new
3625             {
3626 0     0   0 my $this = shift( @_ );
3627 0 0 0     0 my $self = bless( \( my $dummy = ( $_[0] ? 1 : 0 ) ) => ( ref( $this ) || $this ) );
3628             }
3629              
3630             sub clone
3631             {
3632 0     0   0 my $self = shift( @_ );
3633 0 0       0 unless( ref( $self ) )
3634             {
3635 0         0 die( "clone() must be called with an object." );
3636             }
3637 0         0 my $copy = $$self;
3638 0         0 my $new = bless( \$copy => ref( $self ) );
3639 0         0 return( $new );
3640             }
3641              
3642 0     0   0 sub false() { $false }
3643              
3644 0     0   0 sub is_bool($) { UNIVERSAL::isa( $_[0], 'Locale::Unicode::Boolean' ) }
3645              
3646 0 0   0   0 sub is_true($) { $_[0] && UNIVERSAL::isa( $_[0], 'Locale::Unicode::Boolean' ) }
3647              
3648 0 0   0   0 sub is_false($) { !$_[0] && UNIVERSAL::isa( $_[0], 'Locale::Unicode::Boolean' ) }
3649              
3650 0     0   0 sub true() { $true }
3651              
3652             sub FREEZE
3653             {
3654 0     0   0 my $self = CORE::shift( @_ );
3655 0   0     0 my $serialiser = CORE::shift( @_ ) // '';
3656 0         0 my $class = CORE::ref( $self );
3657             # Return an array reference rather than a list so this works with Sereal and CBOR
3658             # On or before Sereal version 4.023, Sereal did not support multiple values returned
3659 0 0 0     0 CORE::return( [$class, $$self] ) if( $serialiser eq 'Sereal' && Sereal::Encoder->VERSION <= version->parse( '4.023' ) );
3660             # But Storable want a list with the first element being the serialised element
3661 0         0 CORE::return( $$self );
3662             }
3663              
3664 0     0   0 sub STORABLE_freeze { CORE::return( CORE::shift->FREEZE( @_ ) ); }
3665              
3666 0     0   0 sub STORABLE_thaw { CORE::return( CORE::shift->THAW( @_ ) ); }
3667              
3668             # NOTE: CBOR will call the THAW method with the stored classname as first argument, the constant string CBOR as second argument, and all values returned by FREEZE as remaining arguments.
3669             # NOTE: Storable calls it with a blessed object it created followed with $cloning and any other arguments initially provided by STORABLE_freeze
3670             sub THAW
3671             {
3672 0     0   0 my( $self, undef, @args ) = @_;
3673 0         0 my( $class, $str );
3674 0 0 0     0 if( CORE::scalar( @args ) == 1 && CORE::ref( $args[0] ) eq 'ARRAY' )
3675             {
3676 0         0 ( $class, $str ) = @{$args[0]};
  0         0  
3677             }
3678             else
3679             {
3680 0   0     0 $class = CORE::ref( $self ) || $self;
3681 0         0 $str = CORE::shift( @args );
3682             }
3683             # Storable pattern requires to modify the object it created rather than returning a new one
3684 0 0       0 if( CORE::ref( $self ) )
3685             {
3686 0         0 $$self = $str;
3687 0         0 CORE::return( $self );
3688             }
3689             else
3690             {
3691 0         0 CORE::return( $class->new( $str ) );
3692             }
3693             }
3694              
3695             sub TO_JSON
3696             {
3697             # JSON does not check that the value is a proper true or false. It stupidly assumes this is a string
3698             # The only way to make it understand is to return a scalar ref of 1 or 0
3699             # return( $_[0] ? 'true' : 'false' );
3700 0 0   0   0 return( $_[0] ? \1 : \0 );
3701             }
3702              
3703             # NOTE: Locale::Unicode::Exception class
3704             package Locale::Unicode::Exception;
3705             BEGIN
3706             {
3707 3     3   23 use strict;
  3         6  
  3         99  
3708 3     3   14 use warnings;
  3         5  
  3         147  
3709 3     3   13 use vars qw( $VERSION );
  3         5  
  3         6184  
3710             use overload (
3711             '""' => 'as_string',
3712 1     1   881 bool => sub{ $_[0] },
3713 3         22 fallback => 1,
3714 3     3   18 );
  3         5  
3715 3     3   346 our $VERSION = 'v0.1.0';
3716             };
3717 3     3   26 use strict;
  3         6  
  3         65  
3718 3     3   12 use warnings;
  3         37  
  3         193  
3719 3     3   19 use overloading;
  3         47  
  3         1584  
3720              
3721             sub new
3722             {
3723 1     1   4 my $this = shift( @_ );
3724 1   33     7 my $self = bless( {} => ( ref( $this ) || $this ) );
3725 1         6 my @info = caller;
3726 1         52 @$self{ qw( package file line ) } = @info[0..2];
3727 1         4 my $args = {};
3728 1 50       4 if( scalar( @_ ) == 1 )
3729             {
3730 1 50 50     7 if( ( ref( $_[0] ) || '' ) eq 'HASH' )
    0 0        
3731             {
3732 1         3 $args = shift( @_ );
3733 1 50       6 if( $args->{skip_frames} )
3734             {
3735 1         10 @info = caller( int( $args->{skip_frames} ) );
3736 1         5 @$self{ qw( package file line ) } = @info[0..2];
3737             }
3738 1   50     4 $args->{message} ||= '';
3739 1         4 foreach my $k ( qw( package file line message code type retry_after ) )
3740             {
3741 7 100       21 $self->{ $k } = $args->{ $k } if( CORE::exists( $args->{ $k } ) );
3742             }
3743             }
3744             elsif( ref( $_[0] ) && $_[0]->isa( 'Locale::Unicode::Exception' ) )
3745             {
3746 0         0 my $o = $args->{object} = shift( @_ );
3747 0         0 $self->{message} = $o->message;
3748 0         0 $self->{code} = $o->code;
3749 0         0 $self->{type} = $o->type;
3750 0         0 $self->{retry_after} = $o->retry_after;
3751             }
3752             else
3753             {
3754 0         0 die( "Unknown argument provided: '", overload::StrVal( $_[0] ), "'" );
3755             }
3756             }
3757             else
3758             {
3759 0 0       0 $args->{message} = join( '', map( ref( $_ ) eq 'CODE' ? $_->() : $_, @_ ) );
3760             }
3761 1         6 return( $self );
3762             }
3763              
3764             # This is important as stringification is called by die, so as per the manual page, we need to end with new line
3765             # And will add the stack trace
3766             sub as_string
3767             {
3768 3     3   28 no overloading;
  3         3  
  3         3741  
3769 0     0     my $self = shift( @_ );
3770 0 0 0       return( $self->{_cache_value} ) if( $self->{_cache_value} && !CORE::length( $self->{_reset} // '' ) );
      0        
3771 0           my $str = $self->message;
3772 0           $str = "$str";
3773 0           $str =~ s/\r?\n$//g;
3774 0   0       $str .= sprintf( " within package %s at line %d in file %s", ( $self->{package} // 'undef' ), ( $self->{line} // 'undef' ), ( $self->{file} // 'undef' ) );
      0        
      0        
3775 0           $self->{_cache_value} = $str;
3776 0           CORE::delete( $self->{_reset} );
3777 0           return( $str );
3778             }
3779              
3780 0     0     sub code { return( shift->reset(@_)->_set_get_prop( 'code', @_ ) ); }
3781              
3782 0     0     sub file { return( shift->reset(@_)->_set_get_prop( 'file', @_ ) ); }
3783              
3784 0     0     sub line { return( shift->reset(@_)->_set_get_prop( 'line', @_ ) ); }
3785              
3786 0     0     sub message { return( shift->reset(@_)->_set_get_prop( 'message', @_ ) ); }
3787              
3788 0     0     sub package { return( shift->reset(@_)->_set_get_prop( 'package', @_ ) ); }
3789              
3790             # From perlfunc docmentation on "die":
3791             # "If LIST was empty or made an empty string, and $@ contains an
3792             # object reference that has a "PROPAGATE" method, that method will
3793             # be called with additional file and line number parameters. The
3794             # return value replaces the value in $@; i.e., as if "$@ = eval {
3795             # $@->PROPAGATE(__FILE__, __LINE__) };" were called."
3796             sub PROPAGATE
3797             {
3798 0     0     my( $self, $file, $line ) = @_;
3799 0 0 0       if( defined( $file ) && defined( $line ) )
3800             {
3801 0           my $clone = $self->clone;
3802 0           $clone->file( $file );
3803 0           $clone->line( $line );
3804 0           return( $clone );
3805             }
3806 0           return( $self );
3807             }
3808              
3809             sub reset
3810             {
3811 0     0     my $self = shift( @_ );
3812 0 0 0       if( !CORE::length( $self->{_reset} // '' ) && scalar( @_ ) )
      0        
3813             {
3814 0           $self->{_reset} = scalar( @_ );
3815             }
3816 0           return( $self );
3817             }
3818              
3819             sub rethrow
3820             {
3821 0     0     my $self = shift( @_ );
3822 0 0         return if( !ref( $self ) );
3823 0           die( $self );
3824             }
3825              
3826 0     0     sub retry_after { return( shift->_set_get_prop( 'retry_after', @_ ) ); }
3827              
3828             sub throw
3829             {
3830 0     0     my $self = shift( @_ );
3831 0           my $e;
3832 0 0         if( @_ )
3833             {
3834 0           my $msg = shift( @_ );
3835 0           $e = $self->new({
3836             skip_frames => 1,
3837             message => $msg,
3838             });
3839             }
3840             else
3841             {
3842 0           $e = $self;
3843             }
3844 0           die( $e );
3845             }
3846              
3847 0     0     sub type { return( shift->reset(@_)->_set_get_prop( 'type', @_ ) ); }
3848              
3849             sub _set_get_prop
3850             {
3851 0     0     my $self = shift( @_ );
3852 0   0       my $prop = shift( @_ ) || die( "No object property was provided." );
3853 0 0         $self->{ $prop } = shift( @_ ) if( @_ );
3854 0           return( $self->{ $prop } );
3855             }
3856              
3857             sub FREEZE
3858             {
3859 0     0     my $self = CORE::shift( @_ );
3860 0   0       my $serialiser = CORE::shift( @_ ) // '';
3861 0           my $class = CORE::ref( $self );
3862 0           my %hash = %$self;
3863             # Return an array reference rather than a list so this works with Sereal and CBOR
3864             # On or before Sereal version 4.023, Sereal did not support multiple values returned
3865 0 0 0       CORE::return( [$class, \%hash] ) if( $serialiser eq 'Sereal' && Sereal::Encoder->VERSION <= version->parse( '4.023' ) );
3866             # But Storable want a list with the first element being the serialised element
3867 0           CORE::return( $class, \%hash );
3868             }
3869              
3870 0     0     sub STORABLE_freeze { return( shift->FREEZE( @_ ) ); }
3871              
3872 0     0     sub STORABLE_thaw { return( shift->THAW( @_ ) ); }
3873              
3874             # NOTE: CBOR will call the THAW method with the stored classname as first argument, the constant string CBOR as second argument, and all values returned by FREEZE as remaining arguments.
3875             # NOTE: Storable calls it with a blessed object it created followed with $cloning and any other arguments initially provided by STORABLE_freeze
3876             sub THAW
3877             {
3878 0     0     my( $self, undef, @args ) = @_;
3879 0 0 0       my $ref = ( CORE::scalar( @args ) == 1 && CORE::ref( $args[0] ) eq 'ARRAY' ) ? CORE::shift( @args ) : \@args;
3880 0 0 0       my $class = ( CORE::defined( $ref ) && CORE::ref( $ref ) eq 'ARRAY' && CORE::scalar( @$ref ) > 1 ) ? CORE::shift( @$ref ) : ( CORE::ref( $self ) || $self );
      0        
3881 0 0         my $hash = CORE::ref( $ref ) eq 'ARRAY' ? CORE::shift( @$ref ) : {};
3882 0           my $new;
3883             # Storable pattern requires to modify the object it created rather than returning a new one
3884 0 0         if( CORE::ref( $self ) )
3885             {
3886 0           foreach( CORE::keys( %$hash ) )
3887             {
3888 0           $self->{ $_ } = CORE::delete( $hash->{ $_ } );
3889             }
3890 0           $new = $self;
3891             }
3892             else
3893             {
3894 0           $new = CORE::bless( $hash => $class );
3895             }
3896 0           CORE::return( $new );
3897             }
3898              
3899 0     0     sub TO_JSON { return( shift->as_string ); }
3900              
3901             {
3902             # NOTE: Locale::Unicode::NullObject class
3903             package
3904             Locale::Unicode::NullObject;
3905             BEGIN
3906 0         0 {
3907 3     3   24 use strict;
  3         3  
  3         113  
3908 3     3   14 use warnings;
  3         3  
  3         231  
3909             use overload (
3910 0     0   0 '""' => sub{ '' },
3911 3         22 fallback => 1,
3912 3     3   17 );
  3         4  
3913 3     3   321 use Wanted;
  3     0   17  
  3         410  
3914             };
3915 3     3   20 use strict;
  3         4  
  3         97  
3916 3     3   14 use warnings;
  3         5  
  3         1394  
3917              
3918             sub new
3919             {
3920 0     0     my $this = shift( @_ );
3921 0 0         my $ref = @_ ? { @_ } : {};
3922 0   0       return( bless( $ref => ( ref( $this ) || $this ) ) );
3923             }
3924              
3925             sub AUTOLOAD
3926             {
3927 0     0     my( $method ) = our $AUTOLOAD =~ /([^:]+)$/;
3928 0           my $self = shift( @_ );
3929 0 0         if( want( 'OBJECT' ) )
3930             {
3931 0           rreturn( $self );
3932             }
3933             # Otherwise, we return undef; Empty return returns undef in scalar context and empty list in list context
3934 0           return;
3935             };
3936             }
3937              
3938             1;
3939             # NOTE: POD
3940             __END__
3941              
3942             =encoding utf-8
3943              
3944             =head1 NAME
3945              
3946             Locale::Unicode - Unicode Locale Identifier compliant with BCP47 and CLDR
3947              
3948             =head1 SYNOPSIS
3949              
3950             use Locale::Unicode;
3951             my $locale = Locale::Unicode->new( 'ja-Kana-t-it' ) ||
3952             die( Locale::Unicode->error );
3953             say $locale; # ja-Kana-t-it
3954              
3955             # Some undefined locale in Cyrillic script
3956             my $locale = Locale::Unicode->new( 'und-Cyrl' );
3957             $locale->transform( 'und-latn' );
3958             $locale->mechanism( 'ungegn-2007' );
3959             say $locale; # und-Cyrl-t-und-latn-m0-ungegn-2007
3960             # A locale in Cyrillic, transformed from Latin, according to a UNGEGN specification dated 2007.
3961              
3962             # Enabling fatal exceptions
3963             use v5.34;
3964             use experimental 'try';
3965             no warnings 'experimental';
3966             try
3967             {
3968             my $locale = Locale::Unicode->new( 'x', fatal => 1 );
3969             # More code
3970             }
3971             catch( $e )
3972             {
3973             say "Oops: ", $e->message;
3974             }
3975              
3976             Or, you could set the global variable C<$FATAL_EXCEPTIONS> instead:
3977              
3978             use v5.34;
3979             use experimental 'try';
3980             no warnings 'experimental';
3981             local $Locale::Unicode::FATAL_EXCEPTIONS = 1;
3982             try
3983             {
3984             my $locale = Locale::Unicode->new( 'x' );
3985             # More code
3986             }
3987             catch( $e )
3988             {
3989             say "Oops: ", $e->message;
3990             }
3991              
3992             This API detects when methods are called in object context and return the current object:
3993              
3994             $locale->translation( 'my-software' )->tz( 'jptyo' )->ca( 'japanese' )
3995              
3996             In Scalar or in list context, the value returned is the last value set.
3997              
3998             $locale->translation( 'my-software' ); # my-software
3999             $locale->translation( 'other-software' ); # other-software
4000              
4001             =head1 VERSION
4002              
4003             v0.4.0
4004              
4005             =head1 DESCRIPTION
4006              
4007             This module implements the L<Unicode LDML (Locale Data Markup Language) extensions|https://unicode.org/reports/tr35/#u_Extension>
4008              
4009             It does not enforce the standard, and is merely an API to construct, access and modify locales. It is your responsibility to set the right values.
4010              
4011             The only requirement is to provide a proper L<language|https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier>, which is a 2 or 3-characters code, or a L<privateuse or other grandfathered language tags|https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.8>
4012              
4013             For your convenience, summary of key elements of the standard can be found in this documentation.
4014              
4015             It is lightweight and fast with no dependency outside of L<Scalar::Util> and L<Wanted>. It requires perl C<v5.10.1> minimum to operate.
4016              
4017             The object stringifies, and once its string value is computed, it is cached and re-used until it is changed. Thus repetitive call to L<as_string|/as_string> or to stringification does not incur any speed penalty by recomputing what has not changed.
4018              
4019             See the L<LDML specifications|https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier> fore more information of what composes a Unicode language identifier.
4020              
4021             =head1 CONSTRUCTOR
4022              
4023             =head2 new
4024              
4025             # Sets the language 'en'
4026             my $locale = Locale::Unicode->new( 'en' );
4027             # Sets the language 'en' with territory 'GB'
4028             my $locale = Locale::Unicode->new( 'en-GB' );
4029             # Sets the language 'en' with script 'Latn' and territory 'AU'
4030             my $locale = Locale::Unicode->new( 'en-Latn-AU' );
4031             my $locale = Locale::Unicode->new( 'he-IL-u-ca-hebrew-tz-jeruslm' );
4032             my $locale = Locale::Unicode->new( 'ja-Kana-t-it' );
4033             my $locale = Locale::Unicode->new( 'und-Latn-t-und-cyrl' );
4034             my $locale = Locale::Unicode->new( 'und-Cyrl-t-und-latn-m0-ungegn-2007' );
4035             my $locale = Locale::Unicode->new( 'de-u-co-phonebk-ka-shifted' );
4036             # Machine translated from German to Japanese using an undefined vendor
4037             my $locale = Locale::Unicode->new( 'ja-t-de-t0-und' );
4038             $locale->script( 'Kana' );
4039             $locale->country_code( 'JP' );
4040             # Now: ja-Kana-JP-t-de-t0-und
4041              
4042             This takes a C<locale> as compliant with the BCP47 standard upgraded by the L<LDML specifications|https://unicode.org/reports/tr35>, and an optional hash or hash reference of options and this returns a new object.
4043              
4044             The C<locale> provided is parsed and its components can be accessed and modified using all the methods of this class API.
4045              
4046             If an hash or hash reference of options are provided, it will be used to set or modify the components from the C<locale> provided.
4047              
4048             If an error occurs, an L<exception object|Locale::Unicode::Exception> is set and C<undef> is returned in scalar context, or an empty list in list context. The L<exception object|Locale::Unicode::Exception> can then be retrieved using L<error|/error>, such as:
4049              
4050             my $locale = Locale::Unicode->new( $somthing_bad ) ||
4051             die( Locale::Unicode->error );
4052              
4053             =head1 METHODS
4054              
4055             All the methods below are context sensitive.
4056              
4057             If they are called in an object context, they will return the current C<Locale::Unicode> object for chaining, otherwise, they will return the current value. And if that value is C<undef>, it will return C<undef> in scalar context, but an empty list in list context.
4058              
4059             Also, if an error occurs, it will set an L<exception object|Locale::Unicode::Exception> and returns C<undef> in scalar context, or an empty list in list context.
4060              
4061             =head2 apply
4062              
4063             my $hash_reference = Locale::Unicode->parse( 'ja-Kana-t-it' );
4064             $locale->apply( $hash_reference );
4065              
4066             Provided with an hash reference of key-value pairs, and this will set each corresponding method with the associated value.
4067              
4068             If a property provided has no corresponding method, it emits a warning if L<warnings are enabled|warnings/"warnings::enabled()">
4069              
4070             It returns the current object upon success, or sets an L<error object|Module::Generic::Exception> upon error and returns C<undef> in scalar context, or an empty list in list context.
4071              
4072             =head2 as_string
4073              
4074             Returns the Locale object as a string, based on its latest attributes set.
4075              
4076             The string value returned is computed only once and further call to C<as_string> returns a cached value unless changes were made to the Locale attributes.
4077              
4078             Boolean values are expressed as C<true> for tue values and C<false> for false values. However, if a value is true for a given C<locale> component, it is not explicitly stated by default, since the C<LDML> specifications indicate, it is true implicitly. If, however, you want the true boolean value to be displayed nevertheless, make sure to set the global variable C<$EXPLICIT_BOOLEAN> to a true value.
4079              
4080             For example:
4081              
4082             my $locale = Locale::Unicode->new( 'ko-Kore-KR', {
4083             # You can also use 1 or 'yes' as per the specifications
4084             colNumeric => 'true',
4085             colCaseFirst => 'upper'
4086             });
4087             say $locale; # ko-Kore-KR-u-kf-upper-kn
4088              
4089             local $EXPLICIT_BOOLEAN = 1;
4090             my $locale = Locale::Unicode->new( 'ko-Kore-KR', {
4091             # You can also use 1 or 'yes' as per the specifications
4092             colNumeric => 'true',
4093             colCaseFirst => 'upper'
4094             });
4095             say $locale; # ko-Kore-KR-u-kf-upper-kn-true
4096              
4097             =head2 base
4098              
4099             my $locale = Locale::Unicode->new( 'en-US' );
4100             say $locale->base; # en-US
4101              
4102             my $locale = Locale::Unicode->new( 'en-Latn-US-posix-t-de-AT-t0-und-x0-medical' );
4103             say $locale->base; # en-Latn-US-posix
4104             $locale->base( 'ja-JP' );
4105             say $locale->base; # ja-JP
4106             say $locale; ja-JP-t-de-AT-t0-und-x0-medical
4107              
4108             This method sets or gets the L<base part|https://datatracker.ietf.org/doc/html/rfc6067#section-2.1> of the C<locale>
4109              
4110             The C<base> part is composed of the L<language_id|/language_id>, an optional L<script|/script>, an optional L<territory|/territory> and zero or more L<variants|/variant>
4111              
4112             If a value is provided, it will replace the current C<locale> object C<base>
4113              
4114             If an improper C<base> value is provided, it will set an L<error object|Locale::Unicode::Exception> and return C<undef> in scalar context and an empty list in list context.
4115              
4116             It returns the current base as a string.
4117              
4118             =head2 break_exclusion
4119              
4120             my $locale = Locale::Unicode->new( 'ja' );
4121             $locale->break_exclusion( 'hani-hira-kata' );
4122             # Now: ja-dx-hani-hira-kata
4123              
4124             This is a Unicode Dictionary Break Exclusion Identifier that specifies scripts to be excluded from dictionary-based text break (for words and lines).
4125              
4126             Sets or gets the Unicode extension C<dx>
4127              
4128             See also L<dx|/dx>
4129              
4130             =head2 ca
4131              
4132             This is an alias for L</calendar>
4133              
4134             =head2 calendar
4135              
4136             my $locale = Locale::Unicode->new( 'th' );
4137             $locale->calendar( 'buddhist' );
4138             # or:
4139             # $locale->ca( 'buddhist' );
4140             # Now: th-u-ca-buddhist
4141             # which is the Thai with Buddist calendar
4142              
4143             Sets or gets the Unicode extension C<ca>, which is a L<calendar identifier|https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier>.
4144              
4145             See the section on L</"BCP47 EXTENSIONS"> for the proper values.
4146              
4147             =head2 canonical
4148              
4149             This returns a L<clone|/clone> of the current object, formatted as per the L<Unicode locale canonical specifications|https://unicode.org/reports/tr35/tr35.html#Canonical_Unicode_Locale_Identifiers>.
4150              
4151             This means that:
4152              
4153             =over 4
4154              
4155             =item * C<variant>
4156              
4157             Variants are sorted and made in lower case.
4158              
4159             my $locale = Locale::Unicode->new( 'en-Scouse-fonipA' );
4160             say $locale->canonical; # en-fonipa-scouse
4161              
4162             Any duplicates are removed as L<per the LDML specifications|https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier>.
4163              
4164             my $locale = Locale::Unicode->new( 'de-1996-fonipa-1996' );
4165             say $locale->canonical; # de-1996-fonipa
4166              
4167             =item * C<territory>
4168              
4169             Territory is made in upper case
4170              
4171             my $locale = Locale::Unicode->new( 'en-us' );
4172             say $locale->canonical; # en-US
4173              
4174             # Spanish as spoken in South America
4175             my $locale = Locale::Unicode->new( 'es-005' );
4176             say $locale->canonical; # es-005
4177              
4178             =item * C<script>
4179              
4180             Script is formatted in title case.
4181              
4182             my $locale = Locale::Unicode->new( 'ja-kana-jp' );
4183             say $locale->canonical; # ja-Kana-JP
4184              
4185             =item * C<language>
4186              
4187             The language code is made in lower case.
4188              
4189             The special C<language> code C<root> is replaced by C<und>
4190              
4191             =back
4192              
4193             See the L<LDML specifications|https://unicode.org/reports/tr35/tr35.html#5.-canonicalizing-syntax> for more information.
4194              
4195             See also the method L<Locale::Unicode::Data/normalise>
4196              
4197             =head2 cf
4198              
4199             This is an alias for L</cu_format>
4200              
4201             =head2 clone
4202              
4203             Clones the current object and returns the newly instantiated copy.
4204              
4205             If an error occurs, this sets an L<exception object|Locale::Unicode::Exception> and returns C<undef> in scalar context, and an empty list in list context.
4206              
4207             =head2 co
4208              
4209             my $locale = Locale::Unicode->new( 'de' );
4210             $locale->collation( 'phonebk' );
4211             $locale->ka( 'shifted' );
4212             # Now: de-u-co-phonebk-ka-shifted
4213              
4214             This is a Unicode collation identifier that specifies a type of collation (sort order).
4215              
4216             This is an alias for L</collation>
4217              
4218             =head2 colAlternate
4219              
4220             my $locale = Locale::Unicode->new( 'de' );
4221             $locale->collation( 'phonebk' );
4222             $locale->ka( 'shifted' );
4223             # Now: de-u-co-phonebk-ka-shifted
4224              
4225             $locale->collation( 'noignore' );
4226             # or similarly:
4227             $locale->collation( 'non-ignorable' );
4228              
4229             Sets alternate handling for variable weights.
4230              
4231             Sets or gets the Unicode extension C<ka>
4232              
4233             See L</"Collation Options"> for more information.
4234              
4235             =head2 colBackwards
4236              
4237             $locale->colBackwards(1); # true
4238             # Now: kb-true
4239             $locale->colBackwards(0); # false
4240             # Now: kb-false
4241              
4242             Sets collation boolean value for backward collation weight.
4243              
4244             Sets or gets the Unicode extension C<kb>
4245              
4246             See L</"Collation Options"> for more information.
4247              
4248             =head2 colCaseFirst
4249              
4250             $locale->colCaseFirst( undef ); # false (default)
4251             $locale->colCaseFirst( 'upper' );
4252             $locale->colCaseFirst( 'lower' );
4253              
4254             Sets or gets the Unicode extension C<kf>
4255              
4256             See L</"Collation Options"> for more information.
4257              
4258             =head2 colCaseLevel
4259              
4260             $locale->colCaseLevel(1); # true
4261             # Now: kc-true
4262             $locale->colCaseLevel(0); # false
4263             # Now: kc-false
4264              
4265             Sets collation boolean value for case level.
4266              
4267             Sets or gets the Unicode extension C<kc>
4268              
4269             See L</"Collation Options"> for more information.
4270              
4271             =head2 colHiraganaQuaternary
4272              
4273             $locale->colHiraganaQuaternary(1); # true
4274             # Now: kh-true
4275             $locale->colHiraganaQuaternary(0); # false
4276             # Now: kh-false
4277              
4278             Sets collation parameter key for special Hiragana handling.
4279              
4280             Sets or gets the Unicode extension C<kh>
4281              
4282             See L</"Collation Options"> for more information.
4283              
4284             =head2 collation
4285              
4286             my $locale = Locale::Unicode->new( 'fr' );
4287             $locale->collation( 'emoji' );
4288             # Now: fr-u-co-emoji
4289              
4290             my $locale = Locale::Unicode->new( 'de' );
4291             $locale->collation( 'phonebk' );
4292             # Now: de-u-co-phonebk
4293             # which is: German using Phonebook sorting
4294              
4295             Sets or gets the Unicode extension C<co>
4296              
4297             This specifies a type of collation (sort order).
4298              
4299             See L</"Unicode extensions"> for possible values and more information on standard.
4300              
4301             See also L</"Collation Options"> for more on collation options.
4302              
4303             =head2 colNormalisation
4304              
4305             This is an alias for L<colNormalization|/colNormalization>
4306              
4307             =head2 colNormalization
4308              
4309             $locale->colNormalization(1); # true
4310             # Now: kk-true
4311             $locale->colNormalization(0); # false
4312             # Now: kk-false
4313              
4314             Sets collation parameter key for normalisation.
4315              
4316             Sets or gets the Unicode extension C<kk>
4317              
4318             See L</"Collation Options"> for more information.
4319              
4320             =head2 colNumeric
4321              
4322             $locale->colNumeric(1); # true
4323             # Now: kn-true
4324             $locale->colNumeric(0); # false
4325             # Now: kn-false
4326              
4327             Sets collation parameter key for numeric handling.
4328              
4329             Sets or gets the Unicode extension C<kn>
4330              
4331             See L</"Collation Options"> for more information.
4332              
4333             =head2 colReorder
4334              
4335             my $locale = Locale::Unicode->new( 'en' );
4336             $locale->colReorder( 'latn-digit' );
4337             # Now: en-u-kr-latn-digit
4338             # Reorder digits after Latin characters.
4339              
4340             my $locale = Locale::Unicode->new( 'en' );
4341             $locale->colReorder( 'arab-cyrl-others-symbol' );
4342             # Now: en-u-kr-arab-cyrl-others-symbol
4343             # Reorder Arabic characters first, then Cyrillic, and put
4344             # symbols at the end—after all other characters.
4345              
4346             Sets collation reorder codes.
4347              
4348             Sets or gets the Unicode extension C<kr>
4349              
4350             See L</"Collation Options"> for more information.
4351              
4352             =head2 shiftedGroup
4353              
4354             This is an alias for L</colValue>
4355              
4356             =head2 colStrength
4357              
4358             $locale->colStrength( 'level1' );
4359             # Now: ks-level1
4360             # or, equivalent:
4361             $locale->colStrength( 'primary' );
4362              
4363             $locale->colStrength( 'level2' );
4364             # or, equivalent:
4365             $locale->colStrength( 'secondary' );
4366              
4367             $locale->colStrength( 'level3' );
4368             # or, equivalent:
4369             $locale->colStrength( 'tertiary' );
4370              
4371             $locale->colStrength( 'level4' );
4372             # or, equivalent:
4373             $locale->colStrength( 'quaternary' );
4374             $locale->colStrength( 'quarternary' );
4375              
4376             $locale->colStrength( 'identic' );
4377             $locale->colStrength( 'identic' );
4378             $locale->colStrength( 'identical' );
4379              
4380             Sets the collation parameter key for collation strength used for comparison.
4381              
4382             Sets or gets the Unicode extension C<ks>
4383              
4384             See L</"Collation Options"> for more information.
4385              
4386             =head2 colValue
4387              
4388             $locale->colValue( 'currency' );
4389             $locale->colValue( 'punct' );
4390             $locale->colValue( 'space' );
4391             $locale->colValue( 'symbol' );
4392              
4393             Sets the collation value for the last reordering group to be affected by L<ka-shifted|/colAlternate>.
4394              
4395             Sets or gets the Unicode extension C<kv>
4396              
4397             See L</"Collation Options"> for more information.
4398              
4399             =head2 colVariableTop
4400              
4401             Sets the string value for the variable top.
4402              
4403             Sets or gets the Unicode extension C<vt>
4404              
4405             See L</"Collation Options"> for more information.
4406              
4407             =head2 core
4408              
4409             my $locale = Locale::Unicode->new( 'ja-Kana-JP-t-de-AT-t0-und-u-ca-japanese-tz-jptyo' );
4410             say $locale->core; # ja-Kana-JP
4411             my $locale = Locale::Unicode->new( 'es-001-valencia-t-und-latn-m0-ungegn-2007' );
4412             say $locale->core; # es-001-valencia
4413              
4414             This is a read-only method.
4415              
4416             It returns the core part of the C<locale>, which is composed of a 2 to 3-characters code, some optional C<script> and C<country> or C<region> code, and some option C<variant> ID.
4417              
4418             =head2 country_code
4419              
4420             my $locale = Locale::Unicode->new( 'en' );
4421             $locale->country_code( 'US' );
4422             # Now: en-US
4423             $locale->country_code( 'GB' );
4424             # Now: en-GB
4425              
4426             Sets or gets the country code part of the C<locale>.
4427              
4428             A country code should be an ISO 3166 2-letters code, but keep in mind that the C<LDML> (Locale Data Markup Language) accepts old data to ensure stability.
4429              
4430             Note that when you set a country code, it will automatically unset any L<region|/region> code.
4431              
4432             my $locale = Locale::Unicode->new( 'en-001' );
4433             say $locale->region; # 001
4434             $locale->country_code( 'US' );
4435             say $locale->region; # undef
4436             say $locale; # en-US
4437              
4438             You can use L</territory> alternatively.
4439              
4440             =head2 cu
4441              
4442             my $locale = Locale::Unicode->new( 'ja' );
4443             $locale->cu( 'jpy' );
4444             # Now: ja-u-cu-jpy
4445             # which is the Japanese Yens
4446              
4447             This is a Unicode currency identifier that specifies a type of currency (ISO 4217 code.
4448              
4449             This is an alias for L</currency>
4450              
4451             =head2 cu_format
4452              
4453             # Using minus sign symbol for negative numbers
4454             $locale->cf( 'standard' );
4455             # Using parentheses for negative numbers
4456             $locale->cf( 'account' );
4457              
4458             This is a currency format identifier such as C<standard> or C<account>
4459              
4460             Sets or gets the Unicode extension C<cf>
4461              
4462             See the section on L</"BCP47 EXTENSIONS"> for the proper values.
4463              
4464             =head2 currency
4465              
4466             my $locale = Locale::Unicode->new( 'ja' );
4467             $locale->currency( 'jpy' );
4468             # or
4469             # $locale->cu( 'jpy' );
4470             # Now: ja-u-cu-jpy
4471             # which is the Japanese yens
4472              
4473             Sets or gets the Unicode extension C<cu>
4474              
4475             This specifies a type of ISO4217 currency code.
4476              
4477             =head2 d0
4478              
4479             This is an alias for L</destination>
4480              
4481             =head2 dest
4482              
4483             This is an alias for L</destination>
4484              
4485             =head2 destination
4486              
4487             Sets or gets the Transformation extension C<d0> for destination.
4488              
4489             See the section on L</"Transform extensions"> for more information.
4490              
4491             =head2 dx
4492              
4493             This is an alias for L</break_exclusion>
4494              
4495             =head2 em
4496              
4497             This is an alias for L</emoji>
4498              
4499             =head2 emoji
4500              
4501             This is a Unicode Emoji Presentation Style Identifier that specifies a request for the preferred emoji presentation style.
4502              
4503             Sets or gets the Unicode extension C<em>.
4504              
4505             =head2 error
4506              
4507             Used as a mutator, this sets and L<exception object|Locale::Unicode::Exception> and returns an C<Locale::Unicode::NullObject> in object context (such as when chaining), or C<undef> in scalar context, or an empty list in list context.
4508              
4509             The C<Locale::Unicode::NullObject> class prevents the perl error of C<Can't call method "%s" on an undefined value> (see L<perldiag>). Upon the last method chained, C<undef> is returned in scalar context or an empty list in list context.
4510              
4511             For example:
4512              
4513             my $locale = Locale::Unicode->new( 'ja' );
4514             $locale->translation( 'my-software' )->transform_locale( $bad_value )->tz( 'jptyo' ) ||
4515             die( $locale->error );
4516              
4517             In this example, C<jptyo> will never be set, because C<transform_locale> triggered an exception that returned an C<Locale::Unicode::NullObject> object catching all further method calls, but eventually we get the error and die.
4518              
4519             =head2 extended
4520              
4521             # Chinese, Mandarin, Simplified script, as used in China
4522             my $locale = Locale::Unicode->new( 'zh-cmn-Hans-CN' );
4523             say $locale->extended; # cmn
4524              
4525             # Mandarin Chinese, Simplified script, as used in China
4526             my $locale = Locale::Unicode->new( 'cmn-Hans-CN' );
4527             say $locale->extended; # undef
4528             say $locale->script; # Hans
4529              
4530             # Chinese, Cantonese, as used in Hong Kong SAR
4531             my $locale = Locale::Unicode->new( 'zh-yue-HK' );
4532             say $locale->extended; # yue
4533              
4534             Sets or gets the C<extended> C<language> subtags. As per the standard, a language ID may be followed by up to 3 C<extended> C<language> subtag. However, the L<standard states|https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.2>: "Although the ABNF production 'extlang' permits up to three extended language tags in the language tag, extended language subtags MUST NOT include another extended language subtag in their 'Prefix'. That is, the second and third extended language subtag positions in a language tag are permanently reserved and tags that include those subtags in that position are, and will always remain, invalid."
4535              
4536             The regular expression in L<Locale::Unicode> supports the C<extended> language subtag inherited by Unicode from C<BCP47>, although L<it is not strictly supported by the standard|https://unicode.org/reports/tr35/tr35.html#BCP_47_Conformance>. This is done in order to ensure maximum portability and flexibility.
4537              
4538             =head2 false
4539              
4540             This is read-only and returns a L<Locale::Unicode::Boolean> object representing a false value.
4541              
4542             =head2 fatal
4543              
4544             $locale->fatal(1); # Enable fatal exceptions
4545             $locale->fatal(0); # Disable fatal exceptions
4546             my $bool = $locale->fatal;
4547              
4548             Sets or get the boolean value, whether to die upon exception, or not. If set to true, then instead of setting an L<exception object|Locale::Unicode::Exception>, this module will die with an L<exception object|Locale::Unicode::Exception>. You can catch the exception object then after using C<try>. For example:
4549              
4550             use v.5.34; # to be able to use try-catch blocks in perl
4551             use experimental 'try';
4552             no warnings 'experimental';
4553             try
4554             {
4555             my $locale = Locale::Unicode->new( 'x', fatal => 1 );
4556             }
4557             catch( $e )
4558             {
4559             say "Error occurred: ", $e->message;
4560             # Error occurred: Invalid locale value "x" provided.
4561             }
4562              
4563             =head2 first_day
4564              
4565             This is a Unicode First Day Identifier that specifies the preferred first day of the week for calendar display.
4566              
4567             Sets or gets the Unicode extension C<fw>.
4568              
4569             Its values are C<sun>, C<mon>, etc... C<sat>
4570              
4571             =head2 fw
4572              
4573             This is an alias for L</first_day>
4574              
4575             =head2 grandfathered
4576              
4577             # auto-detect and sets an irregular grandfathered language tag
4578             $locale->grandfathered( 'i-klingon' );
4579             # sets a regular grandfathered language tag
4580             $locale->grandfathered( 'zh-hakka' );
4581              
4582             Sets or gets a L<regular|/grandfathered_regular> or L<irregular|/grandfathered_irregular> L<grandfathered language tags|https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.8>
4583              
4584             Those language tags are old-style language tags, that, although they remain valid for most of them, their format has morphed, and most of them have been superseded.
4585              
4586             This is a convenient method that takes a language tag, and based on its value, this will call the method L<regular|/grandfathered_regular> or L<irregular|/grandfathered_irregular>
4587              
4588             If you set a grandfathered language tag, this will automatically unset the L<language|/language>, L<language3|/language3> or L<privateuse|/privateuse> tag value.
4589              
4590             The regular expression in L<Locale::Unicode> supports the C<grandfathered> language subtag inherited by Unicode from C<BCP47>, although L<it is not strictly supported by the standard|https://unicode.org/reports/tr35/tr35.html#BCP_47_Conformance>. This is done in order to ensure maximum portability and flexibility.
4591              
4592             =head2 grandfathered_irregular
4593              
4594             $locale->grandfathered_irregular( 'en-GB-oed' );
4595             $locale->grandfathered_irregular( 'i-ami' );
4596             $locale->grandfathered_irregular( 'i-bnn' );
4597             $locale->grandfathered_irregular( 'i-default' );
4598             $locale->grandfathered_irregular( 'i-enochian' );
4599             $locale->grandfathered_irregular( 'i-hak' );
4600             $locale->grandfathered_irregular( 'i-klingon' );
4601             $locale->grandfathered_irregular( 'i-lux' );
4602             $locale->grandfathered_irregular( 'i-mingo' );
4603             $locale->grandfathered_irregular( 'i-navajo' );
4604             $locale->grandfathered_irregular( 'i-pwn' );
4605             $locale->grandfathered_irregular( 'i-tao' );
4606             $locale->grandfathered_irregular( 'i-tay' );
4607             $locale->grandfathered_irregular( 'i-tsu' );
4608             $locale->grandfathered_irregular( 'sgn-BE-FR' );
4609             $locale->grandfathered_irregular( 'sgn-BE-NL' );
4610             $locale->grandfathered_irregular( 'sgn-CH-DE' );
4611              
4612             Sets or gets an L<irregular grandfathered language tag|https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.8>.
4613              
4614             Setting a value, including C<undef>, will unset the L<language|/language>, L<language3|/language3>, L<privateuse|/privateuse> or L<grandfathered_regular|/grandfathered_regular> tag value.
4615              
4616             The regular expression in L<Locale::Unicode> supports the C<grandfathered> language subtag inherited by Unicode from C<BCP47>, although L<it is not strictly supported by the standard|https://unicode.org/reports/tr35/tr35.html#BCP_47_Conformance>. This is done in order to ensure maximum portability and flexibility.
4617              
4618             =head2 grandfathered_regular
4619              
4620             $locale->grandfathered_regular( 'art-lojban' );
4621             $locale->grandfathered_regular( 'cel-gaulish' );
4622             $locale->grandfathered_regular( 'no-bok' );
4623             $locale->grandfathered_regular( 'no-nyn' );
4624             $locale->grandfathered_regular( 'zh-guoyu' );
4625             $locale->grandfathered_regular( 'zh-hakka' );
4626             $locale->grandfathered_regular( 'zh-min' );
4627             $locale->grandfathered_regular( 'zh-min-nan' );
4628             $locale->grandfathered_regular( 'zh-xiang' );
4629              
4630             Sets or gets a L<regular grandfathered language tag|https://www.rfc-editor.org/rfc/rfc5646.html#section-2.2.8>.
4631              
4632             Setting a value, including C<undef>, will unset the L<language|/language>, L<language3|/language3>, L<privateuse|/privateuse> or L<grandfathered_irregular|/grandfathered_irregular> tag value.
4633              
4634             The regular expression in L<Locale::Unicode> supports the C<grandfathered> language subtag inherited by Unicode from C<BCP47>, although L<it is not strictly supported by the standard|https://unicode.org/reports/tr35/tr35.html#BCP_47_Conformance>. This is done in order to ensure maximum portability and flexibility.
4635              
4636             =head2 h0
4637              
4638             This is an alias for L</hybrid>
4639              
4640             =head2 hc
4641              
4642             This is an alias for L</hour_cycle>
4643              
4644             =head2 hour_cycle
4645              
4646             This is a Unicode Hour Cycle Identifier that specifies the preferred time cycle.
4647              
4648             Sets or gets the Unicode extension C<hc>.
4649              
4650             =head2 hybrid
4651              
4652             my $locale = Locale::Unicode->new( 'ru' );
4653             $locale->transform( 'en' );
4654             $locale->hybrid(1); # true
4655             # or
4656             # $locale->hybrid( 'hybrid' );
4657             # or
4658             # $locale->h0( 'hybrid' );
4659             # Now: ru-t-en-h0-hybrid
4660             # Hybrid Cyrillic - Runglish
4661              
4662             my $locale = Locale::Unicode->new( 'en' );
4663             $locale->transform( 'zh-hant' );
4664             $locale->hybrid( 'hybrid' );
4665             # Now: en-t-zh-hant-h0-hybrid
4666             # which is Hybrid Latin - Chinglish
4667              
4668             Those are Hybrid Locale Identifiers indicating that the C<t> value is a language that is mixed into the main language tag to form a hybrid.
4669              
4670             Sets or gets the Transformation extension C<h0>.
4671              
4672             See the section on L</"Transform extensions"> for more information.
4673              
4674             =head2 i0
4675              
4676             This is an alias for L</input>
4677              
4678             =head2 k0
4679              
4680             This is an alias for L</keyboard>
4681              
4682             =head2 input
4683              
4684             my $locale = Locale::Unicode->new( 'zh' );
4685             $locale->input( 'pinyin' );
4686             # Now: zh-t-i0-pinyin
4687              
4688             This is an Input Method Engine transformation.
4689              
4690             Sets or gets the Transformation extension C<i0>.
4691              
4692             See the section on L</"Transform extensions"> for more information.
4693              
4694             =head2 ka
4695              
4696             This is an alias for L</colAlternate>
4697              
4698             =head2 kb
4699              
4700             This is an alias for L</colBackwards>
4701              
4702             =head2 kc
4703              
4704             This is an alias for L</colCaseLevel>
4705              
4706             =head2 keyboard
4707              
4708             my $locale = Locale::Unicode->new( 'en' );
4709             $locale->keyboard( 'dvorak' );
4710             # Now: en-t-k0-dvorak
4711              
4712             This is a keyboard transformation, such as used by client-side virtual keyboards.
4713              
4714             Sets or gets the Transformation extension C<k0>.
4715              
4716             See the section on L</"Transform extensions"> for more information.
4717              
4718             =head2 kf
4719              
4720             This is an alias for L</colCaseFirst>
4721              
4722             =head2 kh
4723              
4724             This is an alias for L</colHiraganaQuaternary>
4725              
4726             =head2 kk
4727              
4728             This is an alias for L</colNormalization>
4729              
4730             =head2 kn
4731              
4732             This is an alias for L</colNumeric>
4733              
4734             =head2 kr
4735              
4736             This is an alias for L</colReorder>
4737              
4738             =head2 ks
4739              
4740             This is an alias for L</colStrength>
4741              
4742             =head2 kv
4743              
4744             This is an alias for L</colValue>
4745              
4746             =head2 lang
4747              
4748             # current value: fr-FR
4749             $obj->lang( 'de' );
4750             # Now: de-FR
4751              
4752             Sets or gets the C<language> part of this C<locale> object.
4753              
4754             Note that when you set a 2-letters C<language> code, it automatically will unset any 3-characters C<language> code you would have previously set.
4755              
4756             For example:
4757              
4758             $obj->lang( 'ja' );
4759             # locale is now set with language code 'ja'
4760             $obj->lang3( 'jpn' );
4761             # locale is now set with 3-characters language code 'jpn'
4762             say $obj->lang; # undef
4763              
4764             See also L</language>
4765              
4766             Note that you can alternatively use the method L<locale|/locale>, although strictly speaking a C<locale> is the whole string, while the C<language> is a component of it.
4767              
4768             If you use the L<special locale root|https://unicode.org/reports/tr35/tr35.html#Unicode_language_identifier>, it will be accessible via the method L<language|/language>, although normally this is for 2-characters C<language>
4769              
4770             my $locale = Locale::Unicode->new( 'root' );
4771             say $locale; # root
4772             say $locale->language; # root
4773             say $locale->canonical; # und
4774              
4775             my $locale = Locale::Unicode->new( 'root-t-de-t0-ja-x0-medical' );
4776             say $locale; # root-t-de-t0-und-x0-medical
4777             say $locale->language; # root
4778             say $locale->canonical; # und-t-de-t0-ja-x0-medical
4779             say $locale->canonical->language; # und
4780              
4781             =head2 lang3
4782              
4783             my $locale = Locale::Unicode->new( 'ja' );
4784             say $locale; # ja
4785             $locale->language3( 'jpn' );
4786             say $locale->language; # undef
4787             $locale->script( 'Kana' );
4788             # Now: jpn-Kana
4789              
4790             Sets or gets the L<3-letter ISO 639-2 code|https://www.loc.gov/standards/iso639-2/php/code_list.php/>. Keep in mind, however, that to ensure stability, the C<LDML> (Locale Data Markup Language) also uses old data.
4791              
4792             If you set the 3-characters C<language> code, it will replace any previously set 2-characters C<language> code.
4793              
4794             =head2 language
4795              
4796             This is an alias for L<lang|/lang>
4797              
4798             =head2 language3
4799              
4800             This is an alias for L<lang3|/lang3>
4801              
4802             =head2 language_extended
4803              
4804             my $locale = Locale::Unicode->new( 'zh-cmn-TW' );
4805             say $locale->language; # zh
4806             say $locale->language3; # undef
4807             say $locale->language_id; # zh
4808             say $locale->extended; # cmn
4809             say $locale->language_extended; # zh-cmn
4810             say $locale->country_code; # TW
4811              
4812             my $locale = Locale::Unicode->new( 'ja-JP' );
4813             say $locale->language; # ja
4814             say $locale->extended; # undef
4815             say $locale->language_extended; # ja
4816              
4817             # Okinawan spoken in Japan Southern islands
4818             my $locale = Locale::Unicode->new( 'ryu-JP' );
4819             say $locale->language; # undef
4820             say $locale->language3; # ryu
4821             say $locale->language_id; # ryu
4822             say $locale->language_extended; # ryu
4823              
4824             Read-only. This method returns the extended form of the language subtag, which means the 2 to 3-characters language ID and an optional extended language subtag.
4825              
4826             Extended language subtag serves to provide more granularity to a locale, complementing the primary language subtag.
4827              
4828             For example:
4829              
4830             =over 4
4831              
4832             =item * zh-cmn-Hans-CN (Chinese, Mandarin, Simplified script, as used in China)
4833              
4834             =item * zh-yue-HK (Chinese, Cantonese, as used in Hong Kong SAR)
4835              
4836             =back
4837              
4838             However, with Unicode C<LDML>, this is deprecated, and, for example, C<zh-cmn-TW> would be normalised to just C<zh-TW>. See L<Locale::Unicode::Data/normalise> for more information.
4839              
4840             =head2 language_id
4841              
4842             $locale->language_id( 'ja' );
4843             $locale->language_id( 'ryu' );
4844             $locale->language_id( 'und' );
4845             # Unset the language ID
4846             $locale->language_id( undef );
4847             my $str = $locale->language_id;
4848              
4849             Sets or gets a language ID.
4850              
4851             In mutator mode, if the language ID provided is 3-characters long, then L<language3|/language3> will be called to set it, otherwise L<language|/language> will be called.
4852              
4853             In accessor mode, it returns the language ID whether it is a 2-characters ID accessible via L<language|/language>, or a 3-characters ID accessible via L<language3|/language3>
4854              
4855             =head2 lb
4856              
4857             This is an alias for L</line_break>
4858              
4859             =head2 line_break
4860              
4861             This is a Unicode Line Break Style Identifier that specifies a preferred line break style corresponding to the CSS level 3 line-break option.
4862              
4863             Sets or gets the Unicode extension C<lb>.
4864              
4865             =head2 line_break_word
4866              
4867             This is a Unicode Line Break Word Identifier that specifies a preferred line break word handling behavior corresponding to the CSS level 3 word-break option
4868              
4869             Sets or gets the Unicode extension C<lw>.
4870              
4871             =head2 locale
4872              
4873             This is an alias for L<lang|/lang>
4874              
4875             =head2 locale3
4876              
4877             This is an alias for L<lang3|/lang3>
4878              
4879             =head2 lw
4880              
4881             This is an alias for L</line_break_word>
4882              
4883             =head2 m0
4884              
4885             This is an alias for L</mechanism>
4886              
4887             =head2 measurement
4888              
4889             This is a Unicode Measurement System Identifier that specifies a preferred measurement system.
4890              
4891             Sets or gets the Unicode extension C<ms>.
4892              
4893             =head2 mechanism
4894              
4895             my $locale = Locale::Unicode->new( 'und-Latn' );
4896             $locale->transform( 'ru' );
4897             $locale->mechanism( 'ungegn-2007' );
4898             # Now: und-Latn-t-ru-m0-ungegn-2007
4899             # representing a transformation from United Nations Group of Experts on
4900             # Geographical Names in 2007
4901              
4902             This is a transformation mechanism referencing an authority or rules for a type of transformation.
4903              
4904             Sets or gets the Transformation extension C<m0>.
4905              
4906             See the section on L</"Transform extensions"> for more information.
4907              
4908             =head2 merge
4909              
4910             my $locale1 = Locale::Unicode->new( 'ja-JP' );
4911             my $locale2 = Locale::Unicode->new( 'ja-Kana-hepburn-heploc' );
4912             say $locale1->merge( $locale2 ); # ja-Kana-JP-hepburn-heploc
4913              
4914             Provided with another L<Locale::Unicode> object, or a C<locale> string, and this will merge all of that object property with the current object used to call this method.
4915              
4916             Since a C<locale> can have multiple C<variant>s, merging two C<locale> object, will merge the C<variant>s, while avoiding duplicates, like so:
4917              
4918             my $locale1 = Locale::Unicode->new( 'ja-Kana-posix-hepburn' );
4919             my $locale2 = Locale::Unicode->new( 'ja-JP-hepburn-heploc' );
4920             say $locale1->merge( $locale2 ); # ja-Kana-JP-posix-hepburn-heploc
4921              
4922             Note that it will not sort the variants. For that you want to use the L<canonical|/canonical> method.
4923              
4924             See also the method L<Locale::Unicode::Data/normalise>
4925              
4926             It returns the current object.
4927              
4928             =head2 ms
4929              
4930             This is an alias for L</measurement>
4931              
4932             =head2 mu
4933              
4934             This is an alias for L</unit>
4935              
4936             =head2 nu
4937              
4938             This is an alias for L</number>
4939              
4940             =head2 number
4941              
4942             This is a Unicode Number System Identifier that specifies a type of number system.
4943              
4944             Sets or gets the Unicode extension C<nu>.
4945              
4946             =head2 overlong
4947              
4948             my $locale = Locale::Unicode->new( 'en-US' );
4949             say $locale->overlong; # undef
4950             say $locale->country_code; # US
4951             say $locale->territory; # US
4952             # Changing to overlong USA
4953             $locale->overlong( 'USA' );
4954             say $locale->overlong; # USA
4955             say $locale->country_code; # undef
4956             say $locale->territory; # undef
4957              
4958             But doing the following will not yield what you expect, because the C<overlong> C<territory> would be confused by an L<extended|/extended> language subtag.
4959              
4960             # Italian at Vatican City
4961             my $locale = Locale::Unicode->new( 'it-VAT' );
4962             say $locale->overlong; # undef
4963             say $locale->extended; # VAT
4964              
4965             # Spanish as spoken at Panama
4966             my $locale = Locale::Unicode->new( 'es-PAN-valencia' );
4967             say $locale->overlong; # undef
4968             say $locale->extended; # PAN
4969              
4970             Thus, you cannot expect to have the value for L<overlong|/overlong> set. However, you can set it yourself directly by passing a value to method C<overlong>
4971              
4972             Sets or gets an overlong country code.
4973              
4974             You can normalise those C<overlong> country code to their normal equivalent by using L<Locale::Unicode::Data/normalise>
4975              
4976             =head2 private
4977              
4978             my $locale = Locale::Unicode->new( 'ja-JP' );
4979             $locale->private( 'something-else' );
4980             # Now: ja-JP-x-something-else
4981              
4982             This serves to set or get the value for a private subtag.
4983              
4984             =head2 privateuse
4985              
4986             $locale->privateuse( 'x-abc' );
4987             my $str = $locale->privateuse;
4988              
4989             Sets or gets the L<privateuse|https://www.rfc-editor.org/rfc/rfc5646.html> language tag.
4990              
4991             Note that this use is deprecated. See the L<LDML specifications|https://unicode.org/reports/tr35/tr35.html#BCP_47_Language_Tag_Conversion>
4992              
4993             The regular expression in L<Locale::Unicode> supports the C<privateuse> language subtag inherited by Unicode from C<BCP47>, although L<it is not strictly supported by the standard|https://unicode.org/reports/tr35/tr35.html#BCP_47_Conformance>. This is done in order to ensure maximum portability and flexibility.
4994              
4995             =head2 region
4996              
4997             # current value: fr-FR
4998             $locale->region( '150' );
4999             # Now: fr-150
5000              
5001             Sets or gets the C<region> part of a Unicode locale.
5002              
5003             This is a world region represented by a 3-digits code.
5004              
5005             Note that when you set a region code, it will automatically unset any L<country code|/country_code> code.
5006              
5007             my $locale = Locale::Unicode->new( 'en-US' );
5008             say $locale->country_code; # US
5009             $locale->region( '001' );
5010             say $locale->country_code; # undef
5011             say $locale; # en-001
5012              
5013             Also, be careful that since the region code a padded with leading zeroes, not to turn them inadvertently into integer so that C<001> would not become C<1>. This is particularly true if you store it in a SQL database, where the L<DBI> driver might treat it as a number. You would then have to use L<bind_param|DBI/bind_param>
5014              
5015             Below are the known region codes:
5016              
5017             =over 4
5018              
5019             =item * 001
5020              
5021             World
5022              
5023             =item * 002
5024              
5025             Africa
5026              
5027             =item * 003
5028              
5029             North America
5030              
5031             =item * 005
5032              
5033             South America
5034              
5035             =item * 009
5036              
5037             Oceania
5038              
5039             =item * 011
5040              
5041             Western Africa
5042              
5043             =item * 013
5044              
5045             Central America
5046              
5047             =item * 014
5048              
5049             Eastern Africa
5050              
5051             =item * 015
5052              
5053             Northern Africa
5054              
5055             =item * 017
5056              
5057             Middle Africa
5058              
5059             =item * 018
5060              
5061             Southern Africa
5062              
5063             =item * 019
5064              
5065             Americas
5066              
5067             =item * 021
5068              
5069             Northern America
5070              
5071             =item * 029
5072              
5073             Caribbean
5074              
5075             =item * 030
5076              
5077             Eastern Asia
5078              
5079             =item * 034
5080              
5081             Southern Asia
5082              
5083             =item * 035
5084              
5085             Southeast Asia
5086              
5087             =item * 039
5088              
5089             Southern Europe
5090              
5091             =item * 053
5092              
5093             Australasia
5094              
5095             =item * 054
5096              
5097             Melanesia
5098              
5099             =item * 057
5100              
5101             Micronesian Region
5102              
5103             =item * 061
5104              
5105             Polynesia
5106              
5107             =item * 142
5108              
5109             Asia
5110              
5111             =item * 143
5112              
5113             Central Asia
5114              
5115             =item * 145
5116              
5117             Western Asia
5118              
5119             =item * 150
5120              
5121             Europe
5122              
5123             =item * 151
5124              
5125             Eastern Europe
5126              
5127             =item * 154
5128              
5129             Northern Europe
5130              
5131             =item * 155
5132              
5133             Western Europe
5134              
5135             =item * 202
5136              
5137             Sub-Saharan Africa
5138              
5139             =item * 419
5140              
5141             Latin America
5142              
5143             =back
5144              
5145             =head2 region_override
5146              
5147             my $locale = Locale::Unicode->new( 'en-GB' );
5148             $locale->region_override( 'uszzzz' );
5149             # Now: en-GB-u-rg-uszzzz
5150             # which is a locale for British English but with region-specific defaults set to US.
5151              
5152             This is a Unicode Region Override that specifies an alternate C<country code> or C<region> to use for obtaining certain region-specific default values.
5153              
5154             Sets or gets the Unicode extension C<rg>.
5155              
5156             =head2 reset
5157              
5158             When provided with any argument, this will reset the cached value computed by L</as_string>
5159              
5160             =head2 rg
5161              
5162             This is an alias for L</region_override>
5163              
5164             =head2 s0
5165              
5166             This is an alias for L</source>
5167              
5168             =head2 script
5169              
5170             # current value: zh-Hans
5171             $locale->script( 'Hant' );
5172             # Now: zh-Hant
5173              
5174             Sets or gets the C<script> part of the C<locale> identifier.
5175              
5176             =head2 sd
5177              
5178             This is an alias for L</subdivision>
5179              
5180             =head2 sentence_break
5181              
5182             This is a Unicode Sentence Break Suppressions Identifier that specifies a set of data to be used for suppressing certain sentence breaks.
5183              
5184             Sets or gets the Unicode extension C<ss>.
5185              
5186             =head2 source
5187              
5188             This is a transformation source for non-languages or scripts, such as fullwidth-halfwidth conversion.
5189              
5190             Sets or gets the Transformation extension C<s0>.
5191              
5192             See the section on L</"Transform extensions"> for more information.
5193              
5194             =head2 ss
5195              
5196             This is an alias for L</sentence_break>
5197              
5198             =head2 subdivision
5199              
5200             my $locale = Locale::Unicode->new( 'gsw' );
5201             $locale->subdivision( 'chzh' );
5202             # or
5203             # $locale->sd( 'chzh' );
5204             # Now: gsw-u-sd-chzh
5205              
5206             my $locale = Locale::Unicode->new( 'en-US' );
5207             $locale->sd( 'usca' );
5208             # Now: en-US-u-sd-usca
5209              
5210             This is a Unicode Subdivision Identifier that specifies a regional subdivision used for C<locale>. This is typically the States in the U.S., or prefectures in France or Japan, or provinces in Canada.
5211              
5212             Sets or gets the Unicode extension C<sd>.
5213              
5214             Be careful of the rule in the standard. For example, C<en-CA-u-sd-gbsct> would be invalid because C<gb> in C<gbsct> does not match the region subtag C<CA>
5215              
5216             =head2 t0
5217              
5218             This is an alias for L</translation>
5219              
5220             =head2 t_private
5221              
5222             my $locale = Locale::Unicode->new( 'ja' );
5223             $locale->transform( 'und' );
5224             $locale->t_private( 'medical' );
5225             # Now: ja-t-de-t0-und-x0-medical
5226              
5227             This is a private transformation subtag.
5228              
5229             Sets or gets the Transformation private subtag C<x0>.
5230              
5231             =head2 territory
5232              
5233             my $locale = Locale::Unicode->new( 'en' );
5234             # Sets the country code to 'US'
5235             $locale->territory( 'US' );
5236             # Now: en-US
5237             $locale->territory( 'GB' );
5238             # Now: en-GB
5239             # Sets the region to 150
5240             $locale->territory( 150 );
5241              
5242             Sets or gets the country code or the region code part of the C<locale>.
5243              
5244             A country code should be an ISO 3166 2-letters code, but keep in mind that the C<LDML> (Locale Data Markup Language) accepts old data to ensure stability.
5245              
5246             A world C<region> is represented by a 3-digits code.
5247              
5248             In mutator mode, depending on the value, this method C<territory> will set one or the other.
5249              
5250             In accessor mode, this will return the country code, if any, or the region code.
5251              
5252             See also L<country_code|/country_code> and L<region|/region>
5253              
5254             =head2 time_zone
5255              
5256             This is a Unicode Timezone Identifier that specifies a time zone.
5257              
5258             Sets or gets the Unicode extension C<tz>.
5259              
5260             =head2 timezone
5261              
5262             This is an alias for L</time_zone>
5263              
5264             =head2 transform
5265              
5266             my $locale = Locale::Unicode->new( 'ja' );
5267             $locale->transform( 'it' );
5268             # Now: ja-t-it
5269             # which is Japanese, transformed from Italian
5270              
5271             my $locale = Locale::Unicode->new( 'ja-Kana' );
5272             $locale->transform( 'it' );
5273             # Now: ja-Kana-t-it
5274             # which is Japanese Katakana, transformed from Italian
5275              
5276             # 'und' is undefined and is perfectly valid
5277             my $locale = Locale::Unicode->new( 'und-Latn' );
5278             $locale->transform( 'und-cyrl' );
5279             # Now: und-Latn-t-und-cyrl
5280             # which is Latin script, transformed from the Cyrillic script
5281              
5282             Sets or gets the Transformation extension C<t>.
5283              
5284             This takes either a string representing a C<locale> or an L<Locale::Unicode> object.
5285              
5286             If a string is provided, it will be converted to an L<Locale::Unicode> object.
5287              
5288             The resulting value is passed to L<transform_locale|/transform_locale>
5289              
5290             This method is convenient since you do not have to concern yourself whether the value you provide is an object, or not.
5291              
5292             It returns the current object for chaining.
5293              
5294             =head2 transform_locale
5295              
5296             my $locale = Locale::Unicode->new( 'ja' );
5297             my $locale2 = Locale::Unicode->new( 'it' );
5298             $locale->transform_locale( $locale2 );
5299             # Now: ja-t-it
5300             my $object = $locale->transform_locale;
5301              
5302             Sets or gets a L<Locale::Unicode> object used to indicate the original locale subject to transformation.
5303              
5304             This will trigger an L<exception|Locale::Unicode::Exception> if a value, other than C<Locale::Unicode> or an inheriting class object, is set.
5305              
5306             See the section on L</"Transform extensions"> for more information.
5307              
5308             =head2 translation
5309              
5310             my $locale = Locale::Unicode->new( 'ja' );
5311             $locale->transform( 'de' );
5312             $locale->translation( 'und' );
5313             # Now: ja-t-de-t0-und
5314             # Japanese translated from Germany by an undefined vendor
5315              
5316             This is used to indicate content that has been machine translated, or a request for a particular type of machine translation of content.
5317              
5318             Sets or gets the Transformation extension C<t0>.
5319              
5320             See the section on L</"Transform extensions"> for more information.
5321              
5322             =head2 true
5323              
5324             This is read-only and returns a L<Locale::Unicode::Boolean> object representing a true value.
5325              
5326             =head2 tz
5327              
5328             This is an alias for L</time_zone>
5329              
5330             =head2 unit
5331              
5332             This is a Measurement Unit Preference Override that specifies an override for measurement unit preference.
5333              
5334             Sets or gets the Unicode extension C<mu>.
5335              
5336             =head2 va
5337              
5338             This is an alias for L</variant>
5339              
5340             =head2 variant
5341              
5342             This is a Unicode Variant Identifier that specifies a special variant used for locales.
5343              
5344             Sets or gets the Unicode extension C<va>.
5345              
5346             =head2 variants
5347              
5348             This returns the C<variant> part of the C<locale> as an array reference of C<variant> subtags.
5349              
5350             It will always return an array reference whether any C<variant> is set or not.
5351              
5352             my $locale = Locale::Unicode->new( 'en-fonipa-scouse' );
5353             my $ref = $locale->variants; # ['fonipa', 'scouse']
5354              
5355             You could reliably do something like:
5356              
5357             if( scalar( @{$locale->variants} ) > 1 )
5358             {
5359             # Do something
5360             }
5361              
5362             Note that the proper canonical format of a C<locale> has the variants sorted in alphabetical order.
5363              
5364             =head2 vt
5365              
5366             This is an alias for L</colVariableTop>
5367              
5368             =head2 x0
5369              
5370             This is an alias for L</t_private>
5371              
5372             =head1 CLASS FUNCTIONS
5373              
5374             =head2 matches
5375              
5376             Provided with a BCP47 C<locale>, and this returns an hash reference of its components if it matches the BCP47 regular expression, which can be accessed as global class variable C<$LOCALE_RE>.
5377              
5378             If nothing matches, it returns an empty string in scalar context, or an empty list in list context.
5379              
5380             If an error occurs, its sets an L<error object|Module::Generic::Exception> and returns C<undef> in scalar context, or an empty list in list context.
5381              
5382             =head2 parse
5383              
5384             my $hash_ref = Locale::Unicode->parse( 'ja-Kana-t-it' );
5385             # Transcription in Japanese Katakana of an Italian word:
5386             # {
5387             # ext_transform => "t-it",
5388             # ext_transform_subtag => "it",
5389             # language => "ja",
5390             # script => "Kana",
5391             # }
5392             my $hash_ref = Locale::Unicode->parse( 'he-IL-u-ca-hebrew-tz-jeruslm' );
5393             # Represents Hebrew as spoken in Israel, using the traditional Hebrew calendar,
5394             # and in the "Asia/Jerusalem" time zone
5395             # {
5396             # country_code => "IL",
5397             # ext_unicode => "u-ca-hebrew-tz-jeruslm",
5398             # ext_unicode_subtag => "ca-hebrew-tz-jeruslm",
5399             # language => "he",
5400             # }
5401              
5402             Provided with a BCP47 C<locale>, and an optional hash reference like the one returned by L<matches|/matches>, and this will return an hash reference with detailed broken down of the C<locale> embedded information, as per the Unicode BCP47 standard.
5403              
5404             =head2 tz_id2name
5405              
5406             Provided with a CLDR timezone ID, such as C<jptyo> for C<Asia/Tokyo>, and this returns the IANA Olson name equivalent, which, in this case, would be C<Asia/Tokyo>
5407              
5408             If an error occurs, its sets an L<error object|Module::Generic::Exception> and returns C<undef> in scalar context, or an empty list in list context.
5409              
5410             =head2 tz_id2names
5411              
5412             my $ref = Locale::Unicode->tz_id2names( 'unknown' );
5413             # yields an empty array object
5414             my $ref = Locale::Unicode->tz_id2names( 'jptyo' );
5415             # Asia/Tokyo
5416              
5417             Provided with a CLDR timezone ID, such as C<ausyd>, which stands primarily for C<Australia/Sydney>, and this returns an L<array object|Module::Generic::Array> of IANA Olson timezone names, which, in this case, would yield: C<['Australia/Sydney', 'Australia/ACT', 'Australia/Canberra', 'Australia/NSW']>
5418              
5419             The order is set by L<BCP47 timezone data|https://github.com/unicode-org/cldr/blob/main/common/bcp47/timezone.xml>
5420              
5421             If an error occurs, its sets an L<error object|Module::Generic::Exception> and returns C<undef> in scalar context, or an empty list in list context.
5422              
5423             =head2 tz_info
5424              
5425             my $def = Locale::Unicode->tz_id2names( 'jptyo' );
5426             # yields the following hash reference:
5427             # {
5428             # alias => [qw( Asia/Tokyo Japan )],
5429             # desc => "Tokyo, Japan",
5430             # tz => "Asia/Tokyo",
5431             # }
5432             my $def = Locale::Unicode->tz_id2names( 'unknown' );
5433             # yields an empty string (not undef)
5434              
5435             Provided with a CLDR timezone ID, such as C<jptyo> and this returns an hash reference representing the dictionary entry for that ID.
5436              
5437             If no information exists for the given timezone ID, an empty string is returned. C<undef> is returned only for errors.
5438              
5439             If an error occurs, its sets an L<error object|Module::Generic::Exception> and returns C<undef> in scalar context, or an empty list in list context.
5440              
5441             =head2 tz_name2id
5442              
5443             my $id = Locale::Unicode->tz_name2id( 'Asia/Tokyo' );
5444             # jptyo
5445             my $id = Locale::Unicode->tz_name2id( 'Australia/Canberra' );
5446             # ausyd
5447              
5448             Provided with an IANA Olson timezone name, such as C<Asia/Tokyo> and this returns its CLDR equivalent, which, in this case, would be C<jptyo>
5449              
5450             If none exists, an empty string is returned.
5451              
5452             If an error occurs, its sets an L<error object|Module::Generic::Exception> and returns C<undef> in scalar context, or an empty list in list context.
5453              
5454             =head1 OVERLOADING
5455              
5456             Any object from this class is overloaded and stringifies to its C<locale> representation.
5457              
5458             For example:
5459              
5460             my $locale = Locale::Unicode->new('ja-Kana-t-it' );
5461             say $locale; # ja-Kana-t-it
5462             $locale->transform( 'de' );
5463             say $locale; # ja-Kana-t-de
5464              
5465             In boolean context, it always returns true by merely returning the current object instead of falling back on stringifying the object.
5466              
5467             Any other overloading is performed using L<fallback methods|overload/"fallback">.
5468              
5469             =head1 BCP47 EXTENSIONS
5470              
5471             =head2 Unicode extensions
5472              
5473             Example:
5474              
5475             =over 4
5476              
5477             =item * C<gsw-u-sd-chzh>
5478              
5479             =back
5480              
5481             Known L<BCP47 language extensions|https://unicode.org/reports/tr35/#u_Extension> as defined in L<RFC6067|https://datatracker.ietf.org/doc/html/rfc6067> are as follows:
5482              
5483             =over 4
5484              
5485             =item * C<ca>
5486              
5487             A L<Unicode calendar identifier|https://unicode.org/reports/tr35/#UnicodeCalendarIdentifier> that specifies a type of calendar used for formatting and parsing, such as date/time symbols and patterns; it also selects supplemental calendarData used for calendrical calculations. The value can affect the computation of the first day of the week.
5488              
5489             For example:
5490              
5491             =over 8
5492              
5493             =item * C<ja-u-ca-japanese>
5494              
5495             Japanese Imperial calendar
5496              
5497             =item * C<th-u-ca-buddhist>
5498              
5499             Thai with Buddist calendar
5500              
5501             =back
5502              
5503             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/calendar.xml> are:
5504              
5505             =over 8
5506              
5507             =item * C<buddhist>
5508              
5509             Thai Buddhist calendar
5510              
5511             =item * C<chinese>
5512              
5513             Traditional Chinese calendar
5514              
5515             =item * C<coptic>
5516              
5517             Coptic calendar
5518              
5519             =item * C<dangi>
5520              
5521             Traditional Korean calendar
5522              
5523             =item * C<ethioaa>
5524              
5525             Ethiopic calendar, Amete Alem (epoch approx. 5493 B.C.E)
5526              
5527             =item * C<ethiopic>
5528              
5529             Ethiopic calendar, Amete Mihret (epoch approx, 8 C.E.)
5530              
5531             =item * C<gregory>
5532              
5533             Gregorian calendar
5534              
5535             =item * C<hebrew>
5536              
5537             Traditional Hebrew calendar
5538              
5539             =item * C<indian>
5540              
5541             Indian calendar
5542              
5543             =item * C<islamic>
5544              
5545             Hijri calendar
5546              
5547             =item * C<islamic-civil>
5548              
5549             Hijri calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - civil epoch)
5550              
5551             =item * C<islamic-rgsa>
5552              
5553             Hijri calendar, Saudi Arabia sighting
5554              
5555             =item * C<islamic-tbla>
5556              
5557             Hijri calendar, tabular (intercalary years [2,5,7,10,13,16,18,21,24,26,29] - astronomical epoch)
5558              
5559             =item * C<islamic-umalqura>
5560              
5561             Hijri calendar, Umm al-Qura
5562              
5563             =item * C<islamicc>
5564              
5565             Civil (algorithmic) Arabic calendar
5566              
5567             =item * C<iso8601>
5568              
5569             ISO calendar (Gregorian calendar using the ISO 8601 calendar week rules)
5570              
5571             =item * C<japanese>
5572              
5573             Japanese Imperial calendar
5574              
5575             =item * C<persian>
5576              
5577             Persian calendar
5578              
5579             =item * C<roc>
5580              
5581             Republic of China calendar
5582              
5583             =back
5584              
5585             =item * C<cf>
5586              
5587             A L<Unicode currency format identifier|https://unicode.org/reports/tr35/#UnicodeCurrencyFormatIdentifier>
5588              
5589             Typical values are:
5590              
5591             =over 8
5592              
5593             =item * C<standard>
5594              
5595             Default value. Negative numbers use the minusSign symbol.
5596              
5597             =item * C<account>
5598              
5599             Negative numbers use parentheses or equivalent.
5600              
5601             =back
5602              
5603             =item * C<co>
5604              
5605             A L<Unicode collation identifier|https://unicode.org/reports/tr35/#UnicodeCollationIdentifier> that specifies a type of collation (sort order).
5606              
5607             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/collation.xml> are:
5608              
5609             =over 8
5610              
5611             =item * C<big5han>
5612              
5613             Pinyin ordering for Latin, big5 charset ordering for CJK characters (used in Chinese)
5614              
5615             =item * C<compat>
5616              
5617             A previous version of the ordering, for compatibility
5618              
5619             =item * C<dict>
5620              
5621             Dictionary style ordering (such as in Sinhala)
5622              
5623             =item * C<direct>
5624              
5625             Binary code point order (used in Hindi)
5626              
5627             =item * C<ducet>
5628              
5629             The default Unicode collation element table order
5630              
5631             =item * C<emoji>
5632              
5633             Recommended ordering for emoji characters
5634              
5635             =item * C<eor>
5636              
5637             European ordering rules
5638              
5639             =item * C<gb2312>
5640              
5641             Pinyin ordering for Latin, gb2312han charset ordering for CJK characters (used in Chinese)
5642              
5643             =item * C<phonebk>
5644              
5645             Phonebook style ordering (such as in German)
5646              
5647             =item * C<phonetic>
5648              
5649             Phonetic ordering (sorting based on pronunciation)
5650              
5651             =item * C<pinyin>
5652              
5653             Pinyin ordering for Latin and for CJK characters (used in Chinese)
5654              
5655             =item * C<reformed>
5656              
5657             Reformed ordering (such as in Swedish)
5658              
5659             =item * C<search>
5660              
5661             Special collation type for string search
5662              
5663             =item * C<searchjl>
5664              
5665             Special collation type for Korean initial consonant search
5666              
5667             =item * C<standard>
5668              
5669             Default ordering for each language
5670              
5671             =item * C<stroke>
5672              
5673             Pinyin ordering for Latin, stroke order for CJK characters (used in Chinese)
5674              
5675             =item * C<trad>
5676              
5677             Traditional style ordering (such as in Spanish)
5678              
5679             =item * C<unihan>
5680              
5681             Pinyin ordering for Latin, Unihan radical-stroke ordering for CJK characters (used in Chinese)
5682              
5683             =item * C<zhuyin>
5684              
5685             Pinyin ordering for Latin, zhuyin order for Bopomofo and CJK characters (used in Chinese)
5686              
5687             =back
5688              
5689             For example: C<de-u-co-phonebk-ka-shifted> (German using Phonebook sorting, ignore punct.)
5690              
5691             =item * C<cu>
5692              
5693             A L<Unicode Currency Identifier|https://unicode.org/reports/tr35/#UnicodeCurrencyIdentifier> that specifies a type of currency (L<ISO 4217 code|https://github.com/unicode-org/cldr/blob/main/common/bcp47/currency.xml>) consisting of 3 ASCII letters that are or have been valid in ISO 4217, plus certain additional codes that are or have been in common use.
5694              
5695             For example: C<ja-u-cu-jpy> (Japanese yens)
5696              
5697             =item * C<dx>
5698              
5699             A L<Unicode Dictionary Break Exclusion Identifier|https://unicode.org/reports/tr35/#UnicodeDictionaryBreakExclusionIdentifier> specifies scripts to be excluded from dictionary-based text break (for words and lines).
5700              
5701             A proper value is one or more Unicode script subtags separated by hyphen. Their order is not important, but canonical order is alphabetical, such as C<dx-hani-thai>
5702              
5703             For example:
5704              
5705             =over 8
5706              
5707             =item * C<dx-hani-hira-kata>
5708              
5709             =item * C<dx-thai-hani>
5710              
5711             =back
5712              
5713             =item * C<em>
5714              
5715             A L<Unicode Emoji Presentation Style Identifier|https://unicode.org/reports/tr35/#UnicodeEmojiPresentationStyleIdentifier> specifies a request for the preferred emoji presentation style.
5716              
5717             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/variant.xml> are:
5718              
5719             =over 8
5720              
5721             =item * C<emoji>
5722              
5723             Use an emoji presentation for emoji characters if possible.
5724              
5725             =item * C<text>
5726              
5727             Use a text presentation for emoji characters if possible.
5728              
5729             =item * C<default>
5730              
5731             Use the default presentation for emoji characters as specified in L<UTR #51|https://www.unicode.org/reports/tr51/#Presentation_Style>
5732              
5733             =back
5734              
5735             =item * C<fw>
5736              
5737             A L<Unicode First Day Identifier|https://unicode.org/reports/tr35/#UnicodeFirstDayIdentifier> defines the preferred first day of the week for calendar display.
5738              
5739             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/calendar.xml> are:
5740              
5741             =over 8
5742              
5743             =item * C<sun>
5744              
5745             Sunday
5746              
5747             =item * C<mon>
5748              
5749             Monday
5750              
5751             =item * C<tue>
5752              
5753             Tuesday
5754              
5755             =item * C<wed>
5756              
5757             Wednesday
5758              
5759             =item * C<thu>
5760              
5761             Thursday
5762              
5763             =item * C<fri>
5764              
5765             Friday
5766              
5767             =item * C<sat>
5768              
5769             Saturday
5770              
5771             =back
5772              
5773             =item * C<hc>
5774              
5775             A L<Unicode Hour Cycle Identifier|https://unicode.org/reports/tr35/#UnicodeHourCycleIdentifier> defines the preferred time cycle.
5776              
5777             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/calendar.xml> are:
5778              
5779             =over 8
5780              
5781             =item * C<h12>
5782              
5783             Hour system using 1–12; corresponds to C<h> in patterns
5784              
5785             =item * C<h23>
5786              
5787             Hour system using 0–23; corresponds to C<H> in patterns
5788              
5789             =item * C<h11>
5790              
5791             Hour system using 0–11; corresponds to C<K> in patterns
5792              
5793             =item * C<h24>
5794              
5795             Hour system using 1–24; corresponds to C<k> in pattern
5796              
5797             =back
5798              
5799             =item * C<lb>
5800              
5801             A L<Unicode Line Break Style Identifier|https://unicode.org/reports/tr35/#UnicodeLineBreakStyleIdentifier> defines a preferred line break style corresponding to the L<CSS level 3 line-break option|https://drafts.csswg.org/css-text/#line-break-property>.
5802              
5803             Possible L<values|https://github.com/unicode-org/cldr/blob/10ed3348d56be1c9fdadeb0a793a9b909eac3151/common/bcp47/segmentation.xml#L16> are:
5804              
5805             =over 8
5806              
5807             =item * C<strict>
5808              
5809             CSS level 3 line-break=strict, e.g. treat CJ as NS
5810              
5811             =item * C<normal>
5812              
5813             CSS level 3 line-break=normal, e.g. treat CJ as ID, break before hyphens for ja,zh
5814              
5815             =item * C<loose>
5816              
5817             CSS lev 3 line-break=loose
5818              
5819             =back
5820              
5821             =item * C<lw>
5822              
5823             A L<Unicode Line Break Word Identifier|https://unicode.org/reports/tr35/#UnicodeLineBreakWordIdentifier> defines preferred line break word handling behavior corresponding to the L<CSS level 3 word-break option|https://drafts.csswg.org/css-text/#word-break-property>.
5824              
5825             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/segmentation.xml> are:
5826              
5827             =over 8
5828              
5829             =item * C<normal>
5830              
5831             CSS level 3 word-break=normal, normal script/language behavior for midword breaks
5832              
5833             =item * C<breakall>
5834              
5835             CSS level 3 word-break=break-all, allow midword breaks unless forbidden by lb setting
5836              
5837             =item * C<keepall>
5838              
5839             CSS level 3 word-break=keep-all, prohibit midword breaks except for dictionary breaks
5840              
5841             =item * C<phrase>
5842              
5843             Prioritise keeping natural phrases (of multiple words) together when breaking, used in short text like title and headline
5844              
5845             =back
5846              
5847             =item * C<ms>
5848              
5849             A L<Unicode Measurement System Identifier|https://unicode.org/reports/tr35/#UnicodeMeasurementSystemIdentifier> defines a preferred measurement system. Specifying "ms" in a C<locale> identifier overrides the default value specified by supplemental measurement system data for the region
5850              
5851             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/measure.xml> are:
5852              
5853             =over 8
5854              
5855             =item * C<metric>
5856              
5857             Metric System
5858              
5859             =item * C<ussystem>
5860              
5861             US System of measurement: feet, pints, etc.; pints are 16oz
5862              
5863             =item * C<uksystem>
5864              
5865             UK System of measurement: feet, pints, etc.; pints are 20oz
5866              
5867             =back
5868              
5869             =item * C<mu>
5870              
5871             A L<Measurement Unit Preference Override|https://unicode.org/reports/tr35/#MeasurementUnitPreferenceOverride> defines an override for measurement unit preference.
5872              
5873             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/measure.xml> are:
5874              
5875             =over 8
5876              
5877             =item * C<celsius>
5878              
5879             Celsius as temperature unit
5880              
5881             =item * C<kelvin>
5882              
5883             Kelvin as temperature unit
5884              
5885             =item * C<fahrenhe>
5886              
5887             Fahrenheit as temperature unit
5888              
5889             =back
5890              
5891             =item * C<nu>
5892              
5893             A L<Unicode Number System Identifier|https://unicode.org/reports/tr35/#UnicodeNumberSystemIdentifier> defines a type of number system.
5894              
5895             For example: C<ar-u-nu-native> (Arabic with native digits such as "٠١٢٣٤"), or C<ar-u-nu-latn> (Arabic with Western digits such as "01234")
5896              
5897             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/number.xml> are:
5898              
5899             =over 8
5900              
5901             =item * C<4-letters Unicode script subtag>
5902              
5903             =item * C<arabext>
5904              
5905             Extended Arabic-Indic digits ("arab" means the base Arabic-Indic digits)
5906              
5907             =item * C<armnlow>
5908              
5909             Armenian lowercase numerals
5910              
5911             =item * C<finance>
5912              
5913             Financial numerals
5914              
5915             =item * C<fullwide>
5916              
5917             Full width digits
5918              
5919             =item * C<greklow>
5920              
5921             Greek lower case numerals
5922              
5923             =item * C<hanidays>
5924              
5925             Han-character day-of-month numbering for lunar/other traditional calendars
5926              
5927             =item * C<hanidec>
5928              
5929             Positional decimal system using Chinese number ideographs as digits
5930              
5931             =item * C<hansfin>
5932              
5933             Simplified Chinese financial numerals
5934              
5935             =item * C<hantfin>
5936              
5937             Traditional Chinese financial numerals
5938              
5939             =item * C<jpanfin>
5940              
5941             Japanese financial numerals
5942              
5943             =item * C<jpanyear>
5944              
5945             Japanese first-year Gannen numbering for Japanese calendar
5946              
5947             =item * C<lanatham>
5948              
5949             Tai Tham Tham (ecclesiastical) digits
5950              
5951             =item * C<mathbold>
5952              
5953             Mathematical bold digits
5954              
5955             =item * C<mathdbl>
5956              
5957             Mathematical double-struck digits
5958              
5959             =item * C<mathmono>
5960              
5961             Mathematical monospace digits
5962              
5963             =item * C<mathsanb>
5964              
5965             Mathematical sans-serif bold digits
5966              
5967             =item * C<mathsans>
5968              
5969             Mathematical sans-serif digits
5970              
5971             =item * C<mymrepka>
5972              
5973             Myanmar Eastern Pwo Karen digits
5974              
5975             =item * C<mymrpao>
5976              
5977             Myanmar Pao digits
5978              
5979             =item * C<mymrshan>
5980              
5981             Myanmar Shan digits
5982              
5983             =item * C<mymrtlng>
5984              
5985             Myanmar Tai Laing digits
5986              
5987             =item * C<native>
5988              
5989             Native digits
5990              
5991             =item * C<outlined>
5992              
5993             Legacy computing outlined digits
5994              
5995             =item * C<roman>
5996              
5997             Roman numerals
5998              
5999             =item * C<romanlow>
6000              
6001             Roman lowercase numerals
6002              
6003             =item * C<segment>
6004              
6005             Legacy computing segmented digits
6006              
6007             =item * C<tamldec>
6008              
6009             Modern Tamil decimal digits
6010              
6011             =item * C<traditio>
6012              
6013             Traditional numerals
6014              
6015             =back
6016              
6017             =item * C<rg>
6018              
6019             A L<Region Override|https://unicode.org/reports/tr35/#RegionOverride> specifies an alternate region to use for obtaining certain region-specific default values
6020              
6021             For example: C<en-GB-u-rg-uszzzz> representing a C<locale> for British English but with region-specific defaults set to US.
6022              
6023             =item * C<sd>
6024              
6025             A L<Unicode Subdivision Identifier|https://unicode.org/reports/tr35/#UnicodeSubdivisionIdentifier> defines a L<regional subdivision|https://unicode.org/reports/tr35/#Unicode_Subdivision_Codes> used for locales.
6026              
6027             They are called various names, such as a state in the United States, or a prefecture in Japan or France, or a province in Canada.
6028              
6029             For example:
6030              
6031             =over 8
6032              
6033             =item * C<en-u-sd-uszzzz>
6034              
6035             Subdivision codes for unknown values are the region code plus C<zzzz>, such as here with C<uszzzz> for an unknown subdivision of the US.
6036              
6037             =item * C<en-US-u-sd-usca>
6038              
6039             English as used in California, USA
6040              
6041             =back
6042              
6043             C<en-CA-u-sd-gbsct> would be invalid because C<gb> in C<gbsct> does not match the region subtag C<CA>
6044              
6045             =item * C<ss>
6046              
6047             A L<Unicode Sentence Break Suppressions Identifier|https://unicode.org/reports/tr35/#UnicodeSentenceBreakSuppressionsIdentifier> defines a set of data to be used for suppressing certain sentence breaks
6048              
6049             Possible L<values|https://github.com/unicode-org/cldr/blob/10ed3348d56be1c9fdadeb0a793a9b909eac3151/common/bcp47/segmentation.xml#L29> are:
6050              
6051             =over 8
6052              
6053             =item * C<none> (default)
6054              
6055             Do not use sentence break suppressions data
6056              
6057             =item * C<standard>
6058              
6059             Use sentence break suppressions data of type C<standard>
6060              
6061             =back
6062              
6063             =item * C<tz>
6064              
6065             A L<Unicode Timezone Identifier|https://unicode.org/reports/tr35/#UnicodeTimezoneIdentifier> defines a timezone.
6066              
6067             To access those values, check the class functions L</tz_id2name>, L<tz_id2names>, L</tz_info> and L</tz_name2id>
6068              
6069             Possible L<values|https://github.com/unicode-org/cldr/blob/main/common/bcp47/timezone.xml> are:
6070              
6071             =over 8
6072              
6073             =item * C<adalv>
6074              
6075             Name: Andorra
6076              
6077             Time zone: C<Europe/Andorra>
6078              
6079             =item * C<aedxb>
6080              
6081             Name: Dubai, United Arab Emirates
6082              
6083             Time zone: C<Asia/Dubai>
6084              
6085             =item * C<afkbl>
6086              
6087             Name: Kabul, Afghanistan
6088              
6089             Time zone: C<Asia/Kabul>
6090              
6091             =item * C<aganu>
6092              
6093             Name: Antigua
6094              
6095             Time zone: C<America/Antigua>
6096              
6097             =item * C<aiaxa>
6098              
6099             Name: Anguilla
6100              
6101             Time zone: C<America/Anguilla>
6102              
6103             =item * C<altia>
6104              
6105             Name: Tirane, Albania
6106              
6107             Time zone: C<Europe/Tirane>
6108              
6109             =item * C<amevn>
6110              
6111             Name: Yerevan, Armenia
6112              
6113             Time zone: C<Asia/Yerevan>
6114              
6115             =item * C<ancur>
6116              
6117             Name: Curaçao
6118              
6119             Time zone: C<America/Curacao>
6120              
6121             =item * C<aolad>
6122              
6123             Name: Luanda, Angola
6124              
6125             Time zone: C<Africa/Luanda>
6126              
6127             =item * C<aqams>
6128              
6129             Amundsen-Scott Station, South Pole
6130              
6131             Deprecated. See instead C<nzakl>
6132              
6133             =item * C<aqcas>
6134              
6135             Name: Casey Station, Bailey Peninsula
6136              
6137             Time zone: C<Antarctica/Casey>
6138              
6139             =item * C<aqdav>
6140              
6141             Name: Davis Station, Vestfold Hills
6142              
6143             Time zone: C<Antarctica/Davis>
6144              
6145             =item * C<aqddu>
6146              
6147             Name: Dumont d'Urville Station, Terre Adélie
6148              
6149             Time zone: C<Antarctica/DumontDUrville>
6150              
6151             =item * C<aqmaw>
6152              
6153             Name: Mawson Station, Holme Bay
6154              
6155             Time zone: C<Antarctica/Mawson>
6156              
6157             =item * C<aqmcm>
6158              
6159             Name: McMurdo Station, Ross Island
6160              
6161             Time zone: C<Antarctica/McMurdo>
6162              
6163             =item * C<aqplm>
6164              
6165             Name: Palmer Station, Anvers Island
6166              
6167             Time zone: C<Antarctica/Palmer>
6168              
6169             =item * C<aqrot>
6170              
6171             Name: Rothera Station, Adelaide Island
6172              
6173             Time zone: C<Antarctica/Rothera>
6174              
6175             =item * C<aqsyw>
6176              
6177             Name: Syowa Station, East Ongul Island
6178              
6179             Time zone: C<Antarctica/Syowa>
6180              
6181             =item * C<aqtrl>
6182              
6183             Name: Troll Station, Queen Maud Land
6184              
6185             Time zone: C<Antarctica/Troll>
6186              
6187             =item * C<aqvos>
6188              
6189             Name: Vostok Station, Lake Vostok
6190              
6191             Time zone: C<Antarctica/Vostok>
6192              
6193             =item * C<arbue>
6194              
6195             Name: Buenos Aires, Argentina
6196              
6197             Time zone: C<America/Buenos_Aires>, C<America/Argentina/Buenos_Aires>
6198              
6199             =item * C<arcor>
6200              
6201             Name: Córdoba, Argentina
6202              
6203             Time zone: C<America/Cordoba>, C<America/Argentina/Cordoba>, C<America/Rosario>
6204              
6205             =item * C<arctc>
6206              
6207             Name: Catamarca, Argentina
6208              
6209             Time zone: C<America/Catamarca>, C<America/Argentina/Catamarca>, C<America/Argentina/ComodRivadavia>
6210              
6211             =item * C<arirj>
6212              
6213             Name: La Rioja, Argentina
6214              
6215             Time zone: C<America/Argentina/La_Rioja>
6216              
6217             =item * C<arjuj>
6218              
6219             Name: Jujuy, Argentina
6220              
6221             Time zone: C<America/Jujuy>, C<America/Argentina/Jujuy>
6222              
6223             =item * C<arluq>
6224              
6225             Name: San Luis, Argentina
6226              
6227             Time zone: C<America/Argentina/San_Luis>
6228              
6229             =item * C<armdz>
6230              
6231             Name: Mendoza, Argentina
6232              
6233             Time zone: C<America/Mendoza>, C<America/Argentina/Mendoza>
6234              
6235             =item * C<arrgl>
6236              
6237             Name: Río Gallegos, Argentina
6238              
6239             Time zone: C<America/Argentina/Rio_Gallegos>
6240              
6241             =item * C<arsla>
6242              
6243             Name: Salta, Argentina
6244              
6245             Time zone: C<America/Argentina/Salta>
6246              
6247             =item * C<artuc>
6248              
6249             Name: Tucumán, Argentina
6250              
6251             Time zone: C<America/Argentina/Tucuman>
6252              
6253             =item * C<aruaq>
6254              
6255             Name: San Juan, Argentina
6256              
6257             Time zone: C<America/Argentina/San_Juan>
6258              
6259             =item * C<arush>
6260              
6261             Name: Ushuaia, Argentina
6262              
6263             Time zone: C<America/Argentina/Ushuaia>
6264              
6265             =item * C<asppg>
6266              
6267             Name: Pago Pago, American Samoa
6268              
6269             Time zone: C<Pacific/Pago_Pago>, C<Pacific/Samoa>, C<US/Samoa>
6270              
6271             =item * C<atvie>
6272              
6273             Name: Vienna, Austria
6274              
6275             Time zone: C<Europe/Vienna>
6276              
6277             =item * C<auadl>
6278              
6279             Name: Adelaide, Australia
6280              
6281             Time zone: C<Australia/Adelaide>, C<Australia/South>
6282              
6283             =item * C<aubhq>
6284              
6285             Name: Broken Hill, Australia
6286              
6287             Time zone: C<Australia/Broken_Hill>, C<Australia/Yancowinna>
6288              
6289             =item * C<aubne>
6290              
6291             Name: Brisbane, Australia
6292              
6293             Time zone: C<Australia/Brisbane>, C<Australia/Queensland>
6294              
6295             =item * C<audrw>
6296              
6297             Name: Darwin, Australia
6298              
6299             Time zone: C<Australia/Darwin>, C<Australia/North>
6300              
6301             =item * C<aueuc>
6302              
6303             Name: Eucla, Australia
6304              
6305             Time zone: C<Australia/Eucla>
6306              
6307             =item * C<auhba>
6308              
6309             Name: Hobart, Australia
6310              
6311             Time zone: C<Australia/Hobart>, C<Australia/Tasmania>, C<Australia/Currie>
6312              
6313             =item * C<aukns>
6314              
6315             Currie, Australia
6316              
6317             Deprecated. See instead C<auhba>
6318              
6319             =item * C<auldc>
6320              
6321             Name: Lindeman Island, Australia
6322              
6323             Time zone: C<Australia/Lindeman>
6324              
6325             =item * C<auldh>
6326              
6327             Name: Lord Howe Island, Australia
6328              
6329             Time zone: C<Australia/Lord_Howe>, C<Australia/LHI>
6330              
6331             =item * C<aumel>
6332              
6333             Name: Melbourne, Australia
6334              
6335             Time zone: C<Australia/Melbourne>, C<Australia/Victoria>
6336              
6337             =item * C<aumqi>
6338              
6339             Name: Macquarie Island Station, Macquarie Island
6340              
6341             Time zone: C<Antarctica/Macquarie>
6342              
6343             =item * C<auper>
6344              
6345             Name: Perth, Australia
6346              
6347             Time zone: C<Australia/Perth>, C<Australia/West>
6348              
6349             =item * C<ausyd>
6350              
6351             Name: Sydney, Australia
6352              
6353             Time zone: C<Australia/Sydney>, C<Australia/ACT>, C<Australia/Canberra>, C<Australia/NSW>
6354              
6355             =item * C<awaua>
6356              
6357             Name: Aruba
6358              
6359             Time zone: C<America/Aruba>
6360              
6361             =item * C<azbak>
6362              
6363             Name: Baku, Azerbaijan
6364              
6365             Time zone: C<Asia/Baku>
6366              
6367             =item * C<basjj>
6368              
6369             Name: Sarajevo, Bosnia and Herzegovina
6370              
6371             Time zone: C<Europe/Sarajevo>
6372              
6373             =item * C<bbbgi>
6374              
6375             Name: Barbados
6376              
6377             Time zone: C<America/Barbados>
6378              
6379             =item * C<bddac>
6380              
6381             Name: Dhaka, Bangladesh
6382              
6383             Time zone: C<Asia/Dhaka>, C<Asia/Dacca>
6384              
6385             =item * C<bebru>
6386              
6387             Name: Brussels, Belgium
6388              
6389             Time zone: C<Europe/Brussels>
6390              
6391             =item * C<bfoua>
6392              
6393             Name: Ouagadougou, Burkina Faso
6394              
6395             Time zone: C<Africa/Ouagadougou>
6396              
6397             =item * C<bgsof>
6398              
6399             Name: Sofia, Bulgaria
6400              
6401             Time zone: C<Europe/Sofia>
6402              
6403             =item * C<bhbah>
6404              
6405             Name: Bahrain
6406              
6407             Time zone: C<Asia/Bahrain>
6408              
6409             =item * C<bibjm>
6410              
6411             Name: Bujumbura, Burundi
6412              
6413             Time zone: C<Africa/Bujumbura>
6414              
6415             =item * C<bjptn>
6416              
6417             Name: Porto-Novo, Benin
6418              
6419             Time zone: C<Africa/Porto-Novo>
6420              
6421             =item * C<bmbda>
6422              
6423             Name: Bermuda
6424              
6425             Time zone: C<Atlantic/Bermuda>
6426              
6427             =item * C<bnbwn>
6428              
6429             Name: Brunei
6430              
6431             Time zone: C<Asia/Brunei>
6432              
6433             =item * C<bolpb>
6434              
6435             Name: La Paz, Bolivia
6436              
6437             Time zone: C<America/La_Paz>
6438              
6439             =item * C<bqkra>
6440              
6441             Name: Bonaire, Sint Estatius and Saba
6442              
6443             Time zone: C<America/Kralendijk>
6444              
6445             =item * C<braux>
6446              
6447             Name: Araguaína, Brazil
6448              
6449             Time zone: C<America/Araguaina>
6450              
6451             =item * C<brbel>
6452              
6453             Name: Belém, Brazil
6454              
6455             Time zone: C<America/Belem>
6456              
6457             =item * C<brbvb>
6458              
6459             Name: Boa Vista, Brazil
6460              
6461             Time zone: C<America/Boa_Vista>
6462              
6463             =item * C<brcgb>
6464              
6465             Name: Cuiabá, Brazil
6466              
6467             Time zone: C<America/Cuiaba>
6468              
6469             =item * C<brcgr>
6470              
6471             Name: Campo Grande, Brazil
6472              
6473             Time zone: C<America/Campo_Grande>
6474              
6475             =item * C<brern>
6476              
6477             Name: Eirunepé, Brazil
6478              
6479             Time zone: C<America/Eirunepe>
6480              
6481             =item * C<brfen>
6482              
6483             Name: Fernando de Noronha, Brazil
6484              
6485             Time zone: C<America/Noronha>, C<Brazil/DeNoronha>
6486              
6487             =item * C<brfor>
6488              
6489             Name: Fortaleza, Brazil
6490              
6491             Time zone: C<America/Fortaleza>
6492              
6493             =item * C<brmao>
6494              
6495             Name: Manaus, Brazil
6496              
6497             Time zone: C<America/Manaus>, C<Brazil/West>
6498              
6499             =item * C<brmcz>
6500              
6501             Name: Maceió, Brazil
6502              
6503             Time zone: C<America/Maceio>
6504              
6505             =item * C<brpvh>
6506              
6507             Name: Porto Velho, Brazil
6508              
6509             Time zone: C<America/Porto_Velho>
6510              
6511             =item * C<brrbr>
6512              
6513             Name: Rio Branco, Brazil
6514              
6515             Time zone: C<America/Rio_Branco>, C<America/Porto_Acre>, C<Brazil/Acre>
6516              
6517             =item * C<brrec>
6518              
6519             Name: Recife, Brazil
6520              
6521             Time zone: C<America/Recife>
6522              
6523             =item * C<brsao>
6524              
6525             Name: São Paulo, Brazil
6526              
6527             Time zone: C<America/Sao_Paulo>, C<Brazil/East>
6528              
6529             =item * C<brssa>
6530              
6531             Name: Bahia, Brazil
6532              
6533             Time zone: C<America/Bahia>
6534              
6535             =item * C<brstm>
6536              
6537             Name: Santarém, Brazil
6538              
6539             Time zone: C<America/Santarem>
6540              
6541             =item * C<bsnas>
6542              
6543             Name: Nassau, Bahamas
6544              
6545             Time zone: C<America/Nassau>
6546              
6547             =item * C<btthi>
6548              
6549             Name: Thimphu, Bhutan
6550              
6551             Time zone: C<Asia/Thimphu>, C<Asia/Thimbu>
6552              
6553             =item * C<bwgbe>
6554              
6555             Name: Gaborone, Botswana
6556              
6557             Time zone: C<Africa/Gaborone>
6558              
6559             =item * C<bymsq>
6560              
6561             Name: Minsk, Belarus
6562              
6563             Time zone: C<Europe/Minsk>
6564              
6565             =item * C<bzbze>
6566              
6567             Name: Belize
6568              
6569             Time zone: C<America/Belize>
6570              
6571             =item * C<cacfq>
6572              
6573             Name: Creston, Canada
6574              
6575             Time zone: C<America/Creston>
6576              
6577             =item * C<caedm>
6578              
6579             Name: Edmonton, Canada
6580              
6581             Time zone: C<America/Edmonton>, C<Canada/Mountain>, C<America/Yellowknife>
6582              
6583             =item * C<caffs>
6584              
6585             Rainy River, Canada
6586              
6587             Deprecated. See instead C<cawnp>
6588              
6589             =item * C<cafne>
6590              
6591             Name: Fort Nelson, Canada
6592              
6593             Time zone: C<America/Fort_Nelson>
6594              
6595             =item * C<caglb>
6596              
6597             Name: Glace Bay, Canada
6598              
6599             Time zone: C<America/Glace_Bay>
6600              
6601             =item * C<cagoo>
6602              
6603             Name: Goose Bay, Canada
6604              
6605             Time zone: C<America/Goose_Bay>
6606              
6607             =item * C<cahal>
6608              
6609             Name: Halifax, Canada
6610              
6611             Time zone: C<America/Halifax>, C<Canada/Atlantic>
6612              
6613             =item * C<caiql>
6614              
6615             Name: Iqaluit, Canada
6616              
6617             Time zone: C<America/Iqaluit>, C<America/Pangnirtung>
6618              
6619             =item * C<camon>
6620              
6621             Name: Moncton, Canada
6622              
6623             Time zone: C<America/Moncton>
6624              
6625             =item * C<camtr>
6626              
6627             Montreal, Canada
6628              
6629             Deprecated. See instead C<cator>
6630              
6631             =item * C<capnt>
6632              
6633             Pangnirtung, Canada
6634              
6635             Deprecated. See instead C<caiql>
6636              
6637             =item * C<careb>
6638              
6639             Name: Resolute, Canada
6640              
6641             Time zone: C<America/Resolute>
6642              
6643             =item * C<careg>
6644              
6645             Name: Regina, Canada
6646              
6647             Time zone: C<America/Regina>, C<Canada/East-Saskatchewan>, C<Canada/Saskatchewan>
6648              
6649             =item * C<casjf>
6650              
6651             Name: St. John's, Canada
6652              
6653             Time zone: C<America/St_Johns>, C<Canada/Newfoundland>
6654              
6655             =item * C<canpg>
6656              
6657             Nipigon, Canada
6658              
6659             Deprecated. See instead C<cator>
6660              
6661             =item * C<cathu>
6662              
6663             Thunder Bay, Canada
6664              
6665             Deprecated. See instead C<cator>
6666              
6667             =item * C<cator>
6668              
6669             Name: Toronto, Canada
6670              
6671             Time zone: C<America/Toronto>, C<America/Montreal>, C<Canada/Eastern>, C<America/Nipigon>, C<America/Thunder_Bay>
6672              
6673             =item * C<cavan>
6674              
6675             Name: Vancouver, Canada
6676              
6677             Time zone: C<America/Vancouver>, C<Canada/Pacific>
6678              
6679             =item * C<cawnp>
6680              
6681             Name: Winnipeg, Canada
6682              
6683             Time zone: C<America/Winnipeg>, C<Canada/Central>, C<America/Rainy_River>
6684              
6685             =item * C<caybx>
6686              
6687             Name: Blanc-Sablon, Canada
6688              
6689             Time zone: C<America/Blanc-Sablon>
6690              
6691             =item * C<caycb>
6692              
6693             Name: Cambridge Bay, Canada
6694              
6695             Time zone: C<America/Cambridge_Bay>
6696              
6697             =item * C<cayda>
6698              
6699             Name: Dawson, Canada
6700              
6701             Time zone: C<America/Dawson>
6702              
6703             =item * C<caydq>
6704              
6705             Name: Dawson Creek, Canada
6706              
6707             Time zone: C<America/Dawson_Creek>
6708              
6709             =item * C<cayek>
6710              
6711             Name: Rankin Inlet, Canada
6712              
6713             Time zone: C<America/Rankin_Inlet>
6714              
6715             =item * C<cayev>
6716              
6717             Name: Inuvik, Canada
6718              
6719             Time zone: C<America/Inuvik>
6720              
6721             =item * C<cayxy>
6722              
6723             Name: Whitehorse, Canada
6724              
6725             Time zone: C<America/Whitehorse>, C<Canada/Yukon>
6726              
6727             =item * C<cayyn>
6728              
6729             Name: Swift Current, Canada
6730              
6731             Time zone: C<America/Swift_Current>
6732              
6733             =item * C<cayzf>
6734              
6735             Yellowknife, Canada
6736              
6737             Deprecated. See instead C<caedm>
6738              
6739             =item * C<cayzs>
6740              
6741             Name: Atikokan, Canada
6742              
6743             Time zone: C<America/Coral_Harbour>, C<America/Atikokan>
6744              
6745             =item * C<cccck>
6746              
6747             Name: Cocos (Keeling) Islands
6748              
6749             Time zone: C<Indian/Cocos>
6750              
6751             =item * C<cdfbm>
6752              
6753             Name: Lubumbashi, Democratic Republic of the Congo
6754              
6755             Time zone: C<Africa/Lubumbashi>
6756              
6757             =item * C<cdfih>
6758              
6759             Name: Kinshasa, Democratic Republic of the Congo
6760              
6761             Time zone: C<Africa/Kinshasa>
6762              
6763             =item * C<cfbgf>
6764              
6765             Name: Bangui, Central African Republic
6766              
6767             Time zone: C<Africa/Bangui>
6768              
6769             =item * C<cgbzv>
6770              
6771             Name: Brazzaville, Republic of the Congo
6772              
6773             Time zone: C<Africa/Brazzaville>
6774              
6775             =item * C<chzrh>
6776              
6777             Name: Zurich, Switzerland
6778              
6779             Time zone: C<Europe/Zurich>
6780              
6781             =item * C<ciabj>
6782              
6783             Name: Abidjan, Côte d'Ivoire
6784              
6785             Time zone: C<Africa/Abidjan>
6786              
6787             =item * C<ckrar>
6788              
6789             Name: Rarotonga, Cook Islands
6790              
6791             Time zone: C<Pacific/Rarotonga>
6792              
6793             =item * C<clipc>
6794              
6795             Name: Easter Island, Chile
6796              
6797             Time zone: C<Pacific/Easter>, C<Chile/EasterIsland>
6798              
6799             =item * C<clpuq>
6800              
6801             Name: Punta Arenas, Chile
6802              
6803             Time zone: C<America/Punta_Arenas>
6804              
6805             =item * C<clscl>
6806              
6807             Name: Santiago, Chile
6808              
6809             Time zone: C<America/Santiago>, C<Chile/Continental>
6810              
6811             =item * C<cmdla>
6812              
6813             Name: Douala, Cameroon
6814              
6815             Time zone: C<Africa/Douala>
6816              
6817             =item * C<cnckg>
6818              
6819             Chongqing, China
6820              
6821             Deprecated. See instead C<cnsha>
6822              
6823             =item * C<cnhrb>
6824              
6825             Harbin, China
6826              
6827             Deprecated. See instead C<cnsha>
6828              
6829             =item * C<cnkhg>
6830              
6831             Kashgar, China
6832              
6833             Deprecated. See instead C<cnurc>
6834              
6835             =item * C<cnsha>
6836              
6837             Name: Shanghai, China
6838              
6839             Time zone: C<Asia/Shanghai>, C<Asia/Chongqing>, C<Asia/Chungking>, C<Asia/Harbin>, C<PRC>
6840              
6841             =item * C<cnurc>
6842              
6843             Name: Ürümqi, China
6844              
6845             Time zone: C<Asia/Urumqi>, C<Asia/Kashgar>
6846              
6847             =item * C<cobog>
6848              
6849             Name: Bogotá, Colombia
6850              
6851             Time zone: C<America/Bogota>
6852              
6853             =item * C<crsjo>
6854              
6855             Name: Costa Rica
6856              
6857             Time zone: C<America/Costa_Rica>
6858              
6859             =item * C<cst6cdt>
6860              
6861             Name: POSIX style time zone for US Central Time
6862              
6863             Time zone: C<CST6CDT>
6864              
6865             =item * C<cuhav>
6866              
6867             Name: Havana, Cuba
6868              
6869             Time zone: C<America/Havana>, C<Cuba>
6870              
6871             =item * C<cvrai>
6872              
6873             Name: Cape Verde
6874              
6875             Time zone: C<Atlantic/Cape_Verde>
6876              
6877             =item * C<cxxch>
6878              
6879             Name: Christmas Island
6880              
6881             Time zone: C<Indian/Christmas>
6882              
6883             =item * C<cyfmg>
6884              
6885             Name: Famagusta, Cyprus
6886              
6887             Time zone: C<Asia/Famagusta>
6888              
6889             =item * C<cynic>
6890              
6891             Name: Nicosia, Cyprus
6892              
6893             Time zone: C<Asia/Nicosia>, C<Europe/Nicosia>
6894              
6895             =item * C<czprg>
6896              
6897             Name: Prague, Czech Republic
6898              
6899             Time zone: C<Europe/Prague>
6900              
6901             =item * C<deber>
6902              
6903             Name: Berlin, Germany
6904              
6905             Time zone: C<Europe/Berlin>
6906              
6907             =item * C<debsngn>
6908              
6909             Name: Busingen, Germany
6910              
6911             Time zone: C<Europe/Busingen>
6912              
6913             =item * C<djjib>
6914              
6915             Name: Djibouti
6916              
6917             Time zone: C<Africa/Djibouti>
6918              
6919             =item * C<dkcph>
6920              
6921             Name: Copenhagen, Denmark
6922              
6923             Time zone: C<Europe/Copenhagen>
6924              
6925             =item * C<dmdom>
6926              
6927             Name: Dominica
6928              
6929             Time zone: C<America/Dominica>
6930              
6931             =item * C<dosdq>
6932              
6933             Name: Santo Domingo, Dominican Republic
6934              
6935             Time zone: C<America/Santo_Domingo>
6936              
6937             =item * C<dzalg>
6938              
6939             Name: Algiers, Algeria
6940              
6941             Time zone: C<Africa/Algiers>
6942              
6943             =item * C<ecgps>
6944              
6945             Name: Galápagos Islands, Ecuador
6946              
6947             Time zone: C<Pacific/Galapagos>
6948              
6949             =item * C<ecgye>
6950              
6951             Name: Guayaquil, Ecuador
6952              
6953             Time zone: C<America/Guayaquil>
6954              
6955             =item * C<eetll>
6956              
6957             Name: Tallinn, Estonia
6958              
6959             Time zone: C<Europe/Tallinn>
6960              
6961             =item * C<egcai>
6962              
6963             Name: Cairo, Egypt
6964              
6965             Time zone: C<Africa/Cairo>, C<Egypt>
6966              
6967             =item * C<eheai>
6968              
6969             Name: El Aaiún, Western Sahara
6970              
6971             Time zone: C<Africa/El_Aaiun>
6972              
6973             =item * C<erasm>
6974              
6975             Name: Asmara, Eritrea
6976              
6977             Time zone: C<Africa/Asmera>, C<Africa/Asmara>
6978              
6979             =item * C<esceu>
6980              
6981             Name: Ceuta, Spain
6982              
6983             Time zone: C<Africa/Ceuta>
6984              
6985             =item * C<eslpa>
6986              
6987             Name: Canary Islands, Spain
6988              
6989             Time zone: C<Atlantic/Canary>
6990              
6991             =item * C<esmad>
6992              
6993             Name: Madrid, Spain
6994              
6995             Time zone: C<Europe/Madrid>
6996              
6997             =item * C<est5edt>
6998              
6999             Name: POSIX style time zone for US Eastern Time
7000              
7001             Time zone: C<EST5EDT>
7002              
7003             =item * C<etadd>
7004              
7005             Name: Addis Ababa, Ethiopia
7006              
7007             Time zone: C<Africa/Addis_Ababa>
7008              
7009             =item * C<fihel>
7010              
7011             Name: Helsinki, Finland
7012              
7013             Time zone: C<Europe/Helsinki>
7014              
7015             =item * C<fimhq>
7016              
7017             Name: Mariehamn, Åland, Finland
7018              
7019             Time zone: C<Europe/Mariehamn>
7020              
7021             =item * C<fjsuv>
7022              
7023             Name: Fiji
7024              
7025             Time zone: C<Pacific/Fiji>
7026              
7027             =item * C<fkpsy>
7028              
7029             Name: Stanley, Falkland Islands
7030              
7031             Time zone: C<Atlantic/Stanley>
7032              
7033             =item * C<fmksa>
7034              
7035             Name: Kosrae, Micronesia
7036              
7037             Time zone: C<Pacific/Kosrae>
7038              
7039             =item * C<fmpni>
7040              
7041             Name: Pohnpei, Micronesia
7042              
7043             Time zone: C<Pacific/Ponape>, C<Pacific/Pohnpei>
7044              
7045             =item * C<fmtkk>
7046              
7047             Name: Chuuk, Micronesia
7048              
7049             Time zone: C<Pacific/Truk>, C<Pacific/Chuuk>, C<Pacific/Yap>
7050              
7051             =item * C<fotho>
7052              
7053             Name: Faroe Islands
7054              
7055             Time zone: C<Atlantic/Faeroe>, C<Atlantic/Faroe>
7056              
7057             =item * C<frpar>
7058              
7059             Name: Paris, France
7060              
7061             Time zone: C<Europe/Paris>
7062              
7063             =item * C<galbv>
7064              
7065             Name: Libreville, Gabon
7066              
7067             Time zone: C<Africa/Libreville>
7068              
7069             =item * C<gaza>
7070              
7071             Gaza Strip, Palestinian Territories
7072              
7073             Deprecated. See instead C<gazastrp>
7074              
7075             =item * C<gazastrp>
7076              
7077             Name: Gaza Strip, Palestinian Territories
7078              
7079             Time zone: C<Asia/Gaza>
7080              
7081             =item * C<gblon>
7082              
7083             Name: London, United Kingdom
7084              
7085             Time zone: C<Europe/London>, C<Europe/Belfast>, C<GB>, C<GB-Eire>
7086              
7087             =item * C<gdgnd>
7088              
7089             Name: Grenada
7090              
7091             Time zone: C<America/Grenada>
7092              
7093             =item * C<getbs>
7094              
7095             Name: Tbilisi, Georgia
7096              
7097             Time zone: C<Asia/Tbilisi>
7098              
7099             =item * C<gfcay>
7100              
7101             Name: Cayenne, French Guiana
7102              
7103             Time zone: C<America/Cayenne>
7104              
7105             =item * C<gggci>
7106              
7107             Name: Guernsey
7108              
7109             Time zone: C<Europe/Guernsey>
7110              
7111             =item * C<ghacc>
7112              
7113             Name: Accra, Ghana
7114              
7115             Time zone: C<Africa/Accra>
7116              
7117             =item * C<gigib>
7118              
7119             Name: Gibraltar
7120              
7121             Time zone: C<Europe/Gibraltar>
7122              
7123             =item * C<gldkshvn>
7124              
7125             Name: Danmarkshavn, Greenland
7126              
7127             Time zone: C<America/Danmarkshavn>
7128              
7129             =item * C<glgoh>
7130              
7131             Name: Nuuk (Godthåb), Greenland
7132              
7133             Time zone: C<America/Godthab>, C<America/Nuuk>
7134              
7135             =item * C<globy>
7136              
7137             Name: Ittoqqortoormiit (Scoresbysund), Greenland
7138              
7139             Time zone: C<America/Scoresbysund>
7140              
7141             =item * C<glthu>
7142              
7143             Name: Qaanaaq (Thule), Greenland
7144              
7145             Time zone: C<America/Thule>
7146              
7147             =item * C<gmbjl>
7148              
7149             Name: Banjul, Gambia
7150              
7151             Time zone: C<Africa/Banjul>
7152              
7153             =item * C<gmt>
7154              
7155             Name: Greenwich Mean Time
7156              
7157             Time zone: C<Etc/GMT>, C<Etc/GMT+0>, C<Etc/GMT-0>, C<Etc/GMT0>, C<Etc/Greenwich>, C<GMT>, C<GMT+0>, C<GMT-0>, C<GMT0>, C<Greenwich>
7158              
7159             =item * C<gncky>
7160              
7161             Name: Conakry, Guinea
7162              
7163             Time zone: C<Africa/Conakry>
7164              
7165             =item * C<gpbbr>
7166              
7167             Name: Guadeloupe
7168              
7169             Time zone: C<America/Guadeloupe>
7170              
7171             =item * C<gpmsb>
7172              
7173             Name: Marigot, Saint Martin
7174              
7175             Time zone: C<America/Marigot>
7176              
7177             =item * C<gpsbh>
7178              
7179             Name: Saint Barthélemy
7180              
7181             Time zone: C<America/St_Barthelemy>
7182              
7183             =item * C<gqssg>
7184              
7185             Name: Malabo, Equatorial Guinea
7186              
7187             Time zone: C<Africa/Malabo>
7188              
7189             =item * C<grath>
7190              
7191             Name: Athens, Greece
7192              
7193             Time zone: C<Europe/Athens>
7194              
7195             =item * C<gsgrv>
7196              
7197             Name: South Georgia and the South Sandwich Islands
7198              
7199             Time zone: C<Atlantic/South_Georgia>
7200              
7201             =item * C<gtgua>
7202              
7203             Name: Guatemala
7204              
7205             Time zone: C<America/Guatemala>
7206              
7207             =item * C<gugum>
7208              
7209             Name: Guam
7210              
7211             Time zone: C<Pacific/Guam>
7212              
7213             =item * C<gwoxb>
7214              
7215             Name: Bissau, Guinea-Bissau
7216              
7217             Time zone: C<Africa/Bissau>
7218              
7219             =item * C<gygeo>
7220              
7221             Name: Guyana
7222              
7223             Time zone: C<America/Guyana>
7224              
7225             =item * C<hebron>
7226              
7227             Name: West Bank, Palestinian Territories
7228              
7229             Time zone: C<Asia/Hebron>
7230              
7231             =item * C<hkhkg>
7232              
7233             Name: Hong Kong SAR China
7234              
7235             Time zone: C<Asia/Hong_Kong>, C<Hongkong>
7236              
7237             =item * C<hntgu>
7238              
7239             Name: Tegucigalpa, Honduras
7240              
7241             Time zone: C<America/Tegucigalpa>
7242              
7243             =item * C<hrzag>
7244              
7245             Name: Zagreb, Croatia
7246              
7247             Time zone: C<Europe/Zagreb>
7248              
7249             =item * C<htpap>
7250              
7251             Name: Port-au-Prince, Haiti
7252              
7253             Time zone: C<America/Port-au-Prince>
7254              
7255             =item * C<hubud>
7256              
7257             Name: Budapest, Hungary
7258              
7259             Time zone: C<Europe/Budapest>
7260              
7261             =item * C<iddjj>
7262              
7263             Name: Jayapura, Indonesia
7264              
7265             Time zone: C<Asia/Jayapura>
7266              
7267             =item * C<idjkt>
7268              
7269             Name: Jakarta, Indonesia
7270              
7271             Time zone: C<Asia/Jakarta>
7272              
7273             =item * C<idmak>
7274              
7275             Name: Makassar, Indonesia
7276              
7277             Time zone: C<Asia/Makassar>, C<Asia/Ujung_Pandang>
7278              
7279             =item * C<idpnk>
7280              
7281             Name: Pontianak, Indonesia
7282              
7283             Time zone: C<Asia/Pontianak>
7284              
7285             =item * C<iedub>
7286              
7287             Name: Dublin, Ireland
7288              
7289             Time zone: C<Europe/Dublin>, C<Eire>
7290              
7291             =item * C<imdgs>
7292              
7293             Name: Isle of Man
7294              
7295             Time zone: C<Europe/Isle_of_Man>
7296              
7297             =item * C<inccu>
7298              
7299             Name: Kolkata, India
7300              
7301             Time zone: C<Asia/Calcutta>, C<Asia/Kolkata>
7302              
7303             =item * C<iodga>
7304              
7305             Name: Chagos Archipelago
7306              
7307             Time zone: C<Indian/Chagos>
7308              
7309             =item * C<iqbgw>
7310              
7311             Name: Baghdad, Iraq
7312              
7313             Time zone: C<Asia/Baghdad>
7314              
7315             =item * C<irthr>
7316              
7317             Name: Tehran, Iran
7318              
7319             Time zone: C<Asia/Tehran>, C<Iran>
7320              
7321             =item * C<isrey>
7322              
7323             Name: Reykjavik, Iceland
7324              
7325             Time zone: C<Atlantic/Reykjavik>, C<Iceland>
7326              
7327             =item * C<itrom>
7328              
7329             Name: Rome, Italy
7330              
7331             Time zone: C<Europe/Rome>
7332              
7333             =item * C<jeruslm>
7334              
7335             Name: Jerusalem
7336              
7337             Time zone: C<Asia/Jerusalem>, C<Asia/Tel_Aviv>, C<Israel>
7338              
7339             =item * C<jesth>
7340              
7341             Name: Jersey
7342              
7343             Time zone: C<Europe/Jersey>
7344              
7345             =item * C<jmkin>
7346              
7347             Name: Jamaica
7348              
7349             Time zone: C<America/Jamaica>, C<Jamaica>
7350              
7351             =item * C<joamm>
7352              
7353             Name: Amman, Jordan
7354              
7355             Time zone: C<Asia/Amman>
7356              
7357             =item * C<jptyo>
7358              
7359             Name: Tokyo, Japan
7360              
7361             Time zone: C<Asia/Tokyo>, C<Japan>
7362              
7363             =item * C<kenbo>
7364              
7365             Name: Nairobi, Kenya
7366              
7367             Time zone: C<Africa/Nairobi>
7368              
7369             =item * C<kgfru>
7370              
7371             Name: Bishkek, Kyrgyzstan
7372              
7373             Time zone: C<Asia/Bishkek>
7374              
7375             =item * C<khpnh>
7376              
7377             Name: Phnom Penh, Cambodia
7378              
7379             Time zone: C<Asia/Phnom_Penh>
7380              
7381             =item * C<kicxi>
7382              
7383             Name: Kiritimati, Kiribati
7384              
7385             Time zone: C<Pacific/Kiritimati>
7386              
7387             =item * C<kipho>
7388              
7389             Name: Enderbury Island, Kiribati
7390              
7391             Time zone: C<Pacific/Enderbury>, C<Pacific/Kanton>
7392              
7393             =item * C<kitrw>
7394              
7395             Name: Tarawa, Kiribati
7396              
7397             Time zone: C<Pacific/Tarawa>
7398              
7399             =item * C<kmyva>
7400              
7401             Name: Comoros
7402              
7403             Time zone: C<Indian/Comoro>
7404              
7405             =item * C<knbas>
7406              
7407             Name: Saint Kitts
7408              
7409             Time zone: C<America/St_Kitts>
7410              
7411             =item * C<kpfnj>
7412              
7413             Name: Pyongyang, North Korea
7414              
7415             Time zone: C<Asia/Pyongyang>
7416              
7417             =item * C<krsel>
7418              
7419             Name: Seoul, South Korea
7420              
7421             Time zone: C<Asia/Seoul>, C<ROK>
7422              
7423             =item * C<kwkwi>
7424              
7425             Name: Kuwait
7426              
7427             Time zone: C<Asia/Kuwait>
7428              
7429             =item * C<kygec>
7430              
7431             Name: Cayman Islands
7432              
7433             Time zone: C<America/Cayman>
7434              
7435             =item * C<kzaau>
7436              
7437             Name: Aqtau, Kazakhstan
7438              
7439             Time zone: C<Asia/Aqtau>
7440              
7441             =item * C<kzakx>
7442              
7443             Name: Aqtobe, Kazakhstan
7444              
7445             Time zone: C<Asia/Aqtobe>
7446              
7447             =item * C<kzala>
7448              
7449             Name: Almaty, Kazakhstan
7450              
7451             Time zone: C<Asia/Almaty>
7452              
7453             =item * C<kzguw>
7454              
7455             Name: Atyrau (Guryev), Kazakhstan
7456              
7457             Time zone: C<Asia/Atyrau>
7458              
7459             =item * C<kzksn>
7460              
7461             Name: Qostanay (Kostanay), Kazakhstan
7462              
7463             Time zone: C<Asia/Qostanay>
7464              
7465             =item * C<kzkzo>
7466              
7467             Name: Kyzylorda, Kazakhstan
7468              
7469             Time zone: C<Asia/Qyzylorda>
7470              
7471             =item * C<kzura>
7472              
7473             Name: Oral, Kazakhstan
7474              
7475             Time zone: C<Asia/Oral>
7476              
7477             =item * C<lavte>
7478              
7479             Name: Vientiane, Laos
7480              
7481             Time zone: C<Asia/Vientiane>
7482              
7483             =item * C<lbbey>
7484              
7485             Name: Beirut, Lebanon
7486              
7487             Time zone: C<Asia/Beirut>
7488              
7489             =item * C<lccas>
7490              
7491             Name: Saint Lucia
7492              
7493             Time zone: C<America/St_Lucia>
7494              
7495             =item * C<livdz>
7496              
7497             Name: Vaduz, Liechtenstein
7498              
7499             Time zone: C<Europe/Vaduz>
7500              
7501             =item * C<lkcmb>
7502              
7503             Name: Colombo, Sri Lanka
7504              
7505             Time zone: C<Asia/Colombo>
7506              
7507             =item * C<lrmlw>
7508              
7509             Name: Monrovia, Liberia
7510              
7511             Time zone: C<Africa/Monrovia>
7512              
7513             =item * C<lsmsu>
7514              
7515             Name: Maseru, Lesotho
7516              
7517             Time zone: C<Africa/Maseru>
7518              
7519             =item * C<ltvno>
7520              
7521             Name: Vilnius, Lithuania
7522              
7523             Time zone: C<Europe/Vilnius>
7524              
7525             =item * C<lulux>
7526              
7527             Name: Luxembourg
7528              
7529             Time zone: C<Europe/Luxembourg>
7530              
7531             =item * C<lvrix>
7532              
7533             Name: Riga, Latvia
7534              
7535             Time zone: C<Europe/Riga>
7536              
7537             =item * C<lytip>
7538              
7539             Name: Tripoli, Libya
7540              
7541             Time zone: C<Africa/Tripoli>, C<Libya>
7542              
7543             =item * C<macas>
7544              
7545             Name: Casablanca, Morocco
7546              
7547             Time zone: C<Africa/Casablanca>
7548              
7549             =item * C<mcmon>
7550              
7551             Name: Monaco
7552              
7553             Time zone: C<Europe/Monaco>
7554              
7555             =item * C<mdkiv>
7556              
7557             Name: Chişinău, Moldova
7558              
7559             Time zone: C<Europe/Chisinau>, C<Europe/Tiraspol>
7560              
7561             =item * C<metgd>
7562              
7563             Name: Podgorica, Montenegro
7564              
7565             Time zone: C<Europe/Podgorica>
7566              
7567             =item * C<mgtnr>
7568              
7569             Name: Antananarivo, Madagascar
7570              
7571             Time zone: C<Indian/Antananarivo>
7572              
7573             =item * C<mhkwa>
7574              
7575             Name: Kwajalein, Marshall Islands
7576              
7577             Time zone: C<Pacific/Kwajalein>, C<Kwajalein>
7578              
7579             =item * C<mhmaj>
7580              
7581             Name: Majuro, Marshall Islands
7582              
7583             Time zone: C<Pacific/Majuro>
7584              
7585             =item * C<mkskp>
7586              
7587             Name: Skopje, Macedonia
7588              
7589             Time zone: C<Europe/Skopje>
7590              
7591             =item * C<mlbko>
7592              
7593             Name: Bamako, Mali
7594              
7595             Time zone: C<Africa/Bamako>, C<Africa/Timbuktu>
7596              
7597             =item * C<mmrgn>
7598              
7599             Name: Yangon (Rangoon), Burma
7600              
7601             Time zone: C<Asia/Rangoon>, C<Asia/Yangon>
7602              
7603             =item * C<mncoq>
7604              
7605             Name: Choibalsan, Mongolia
7606              
7607             Time zone: C<Asia/Choibalsan>
7608              
7609             =item * C<mnhvd>
7610              
7611             Name: Khovd (Hovd), Mongolia
7612              
7613             Time zone: C<Asia/Hovd>
7614              
7615             =item * C<mnuln>
7616              
7617             Name: Ulaanbaatar (Ulan Bator), Mongolia
7618              
7619             Time zone: C<Asia/Ulaanbaatar>, C<Asia/Ulan_Bator>
7620              
7621             =item * C<momfm>
7622              
7623             Name: Macau SAR China
7624              
7625             Time zone: C<Asia/Macau>, C<Asia/Macao>
7626              
7627             =item * C<mpspn>
7628              
7629             Name: Saipan, Northern Mariana Islands
7630              
7631             Time zone: C<Pacific/Saipan>
7632              
7633             =item * C<mqfdf>
7634              
7635             Name: Martinique
7636              
7637             Time zone: C<America/Martinique>
7638              
7639             =item * C<mrnkc>
7640              
7641             Name: Nouakchott, Mauritania
7642              
7643             Time zone: C<Africa/Nouakchott>
7644              
7645             =item * C<msmni>
7646              
7647             Name: Montserrat
7648              
7649             Time zone: C<America/Montserrat>
7650              
7651             =item * C<mst7mdt>
7652              
7653             Name: POSIX style time zone for US Mountain Time
7654              
7655             Time zone: C<MST7MDT>
7656              
7657             =item * C<mtmla>
7658              
7659             Name: Malta
7660              
7661             Time zone: C<Europe/Malta>
7662              
7663             =item * C<muplu>
7664              
7665             Name: Mauritius
7666              
7667             Time zone: C<Indian/Mauritius>
7668              
7669             =item * C<mvmle>
7670              
7671             Name: Maldives
7672              
7673             Time zone: C<Indian/Maldives>
7674              
7675             =item * C<mwblz>
7676              
7677             Name: Blantyre, Malawi
7678              
7679             Time zone: C<Africa/Blantyre>
7680              
7681             =item * C<mxchi>
7682              
7683             Name: Chihuahua, Mexico
7684              
7685             Time zone: C<America/Chihuahua>
7686              
7687             =item * C<mxcun>
7688              
7689             Name: Cancún, Mexico
7690              
7691             Time zone: C<America/Cancun>
7692              
7693             =item * C<mxcjs>
7694              
7695             Name: Ciudad Juárez, Mexico
7696              
7697             Time zone: C<America/Ciudad_Juarez>
7698              
7699             =item * C<mxhmo>
7700              
7701             Name: Hermosillo, Mexico
7702              
7703             Time zone: C<America/Hermosillo>
7704              
7705             =item * C<mxmam>
7706              
7707             Name: Matamoros, Mexico
7708              
7709             Time zone: C<America/Matamoros>
7710              
7711             =item * C<mxmex>
7712              
7713             Name: Mexico City, Mexico
7714              
7715             Time zone: C<America/Mexico_City>, C<Mexico/General>
7716              
7717             =item * C<mxmid>
7718              
7719             Name: Mérida, Mexico
7720              
7721             Time zone: C<America/Merida>
7722              
7723             =item * C<mxmty>
7724              
7725             Name: Monterrey, Mexico
7726              
7727             Time zone: C<America/Monterrey>
7728              
7729             =item * C<mxmzt>
7730              
7731             Name: Mazatlán, Mexico
7732              
7733             Time zone: C<America/Mazatlan>, C<Mexico/BajaSur>
7734              
7735             =item * C<mxoji>
7736              
7737             Name: Ojinaga, Mexico
7738              
7739             Time zone: C<America/Ojinaga>
7740              
7741             =item * C<mxpvr>
7742              
7743             Name: Bahía de Banderas, Mexico
7744              
7745             Time zone: C<America/Bahia_Banderas>
7746              
7747             =item * C<mxstis>
7748              
7749             Santa Isabel (Baja California), Mexico
7750              
7751             Deprecated. See instead C<mxtij>
7752              
7753             =item * C<mxtij>
7754              
7755             Name: Tijuana, Mexico
7756              
7757             Time zone: C<America/Tijuana>, C<America/Ensenada>, C<Mexico/BajaNorte>, C<America/Santa_Isabel>
7758              
7759             =item * C<mykch>
7760              
7761             Name: Kuching, Malaysia
7762              
7763             Time zone: C<Asia/Kuching>
7764              
7765             =item * C<mykul>
7766              
7767             Name: Kuala Lumpur, Malaysia
7768              
7769             Time zone: C<Asia/Kuala_Lumpur>
7770              
7771             =item * C<mzmpm>
7772              
7773             Name: Maputo, Mozambique
7774              
7775             Time zone: C<Africa/Maputo>
7776              
7777             =item * C<nawdh>
7778              
7779             Name: Windhoek, Namibia
7780              
7781             Time zone: C<Africa/Windhoek>
7782              
7783             =item * C<ncnou>
7784              
7785             Name: Noumea, New Caledonia
7786              
7787             Time zone: C<Pacific/Noumea>
7788              
7789             =item * C<nenim>
7790              
7791             Name: Niamey, Niger
7792              
7793             Time zone: C<Africa/Niamey>
7794              
7795             =item * C<nfnlk>
7796              
7797             Name: Norfolk Island
7798              
7799             Time zone: C<Pacific/Norfolk>
7800              
7801             =item * C<nglos>
7802              
7803             Name: Lagos, Nigeria
7804              
7805             Time zone: C<Africa/Lagos>
7806              
7807             =item * C<nimga>
7808              
7809             Name: Managua, Nicaragua
7810              
7811             Time zone: C<America/Managua>
7812              
7813             =item * C<nlams>
7814              
7815             Name: Amsterdam, Netherlands
7816              
7817             Time zone: C<Europe/Amsterdam>
7818              
7819             =item * C<noosl>
7820              
7821             Name: Oslo, Norway
7822              
7823             Time zone: C<Europe/Oslo>
7824              
7825             =item * C<npktm>
7826              
7827             Name: Kathmandu, Nepal
7828              
7829             Time zone: C<Asia/Katmandu>, C<Asia/Kathmandu>
7830              
7831             =item * C<nrinu>
7832              
7833             Name: Nauru
7834              
7835             Time zone: C<Pacific/Nauru>
7836              
7837             =item * C<nuiue>
7838              
7839             Name: Niue
7840              
7841             Time zone: C<Pacific/Niue>
7842              
7843             =item * C<nzakl>
7844              
7845             Name: Auckland, New Zealand
7846              
7847             Time zone: C<Pacific/Auckland>, C<Antarctica/South_Pole>, C<NZ>
7848              
7849             =item * C<nzcht>
7850              
7851             Name: Chatham Islands, New Zealand
7852              
7853             Time zone: C<Pacific/Chatham>, C<NZ-CHAT>
7854              
7855             =item * C<ommct>
7856              
7857             Name: Muscat, Oman
7858              
7859             Time zone: C<Asia/Muscat>
7860              
7861             =item * C<papty>
7862              
7863             Name: Panama
7864              
7865             Time zone: C<America/Panama>
7866              
7867             =item * C<pelim>
7868              
7869             Name: Lima, Peru
7870              
7871             Time zone: C<America/Lima>
7872              
7873             =item * C<pfgmr>
7874              
7875             Name: Gambiera Islands, French Polynesia
7876              
7877             Time zone: C<Pacific/Gambier>
7878              
7879             =item * C<pfnhv>
7880              
7881             Name: Marquesas Islands, French Polynesia
7882              
7883             Time zone: C<Pacific/Marquesas>
7884              
7885             =item * C<pfppt>
7886              
7887             Name: Tahiti, French Polynesia
7888              
7889             Time zone: C<Pacific/Tahiti>
7890              
7891             =item * C<pgpom>
7892              
7893             Name: Port Moresby, Papua New Guinea
7894              
7895             Time zone: C<Pacific/Port_Moresby>
7896              
7897             =item * C<pgraw>
7898              
7899             Name: Bougainville, Papua New Guinea
7900              
7901             Time zone: C<Pacific/Bougainville>
7902              
7903             =item * C<phmnl>
7904              
7905             Name: Manila, Philippines
7906              
7907             Time zone: C<Asia/Manila>
7908              
7909             =item * C<pkkhi>
7910              
7911             Name: Karachi, Pakistan
7912              
7913             Time zone: C<Asia/Karachi>
7914              
7915             =item * C<plwaw>
7916              
7917             Name: Warsaw, Poland
7918              
7919             Time zone: C<Europe/Warsaw>, C<Poland>
7920              
7921             =item * C<pmmqc>
7922              
7923             Name: Saint Pierre and Miquelon
7924              
7925             Time zone: C<America/Miquelon>
7926              
7927             =item * C<pnpcn>
7928              
7929             Name: Pitcairn Islands
7930              
7931             Time zone: C<Pacific/Pitcairn>
7932              
7933             =item * C<prsju>
7934              
7935             Name: Puerto Rico
7936              
7937             Time zone: C<America/Puerto_Rico>
7938              
7939             =item * C<pst8pdt>
7940              
7941             Name: POSIX style time zone for US Pacific Time
7942              
7943             Time zone: C<PST8PDT>
7944              
7945             =item * C<ptfnc>
7946              
7947             Name: Madeira, Portugal
7948              
7949             Time zone: C<Atlantic/Madeira>
7950              
7951             =item * C<ptlis>
7952              
7953             Name: Lisbon, Portugal
7954              
7955             Time zone: C<Europe/Lisbon>, C<Portugal>
7956              
7957             =item * C<ptpdl>
7958              
7959             Name: Azores, Portugal
7960              
7961             Time zone: C<Atlantic/Azores>
7962              
7963             =item * C<pwror>
7964              
7965             Name: Palau
7966              
7967             Time zone: C<Pacific/Palau>
7968              
7969             =item * C<pyasu>
7970              
7971             Name: Asunción, Paraguay
7972              
7973             Time zone: C<America/Asuncion>
7974              
7975             =item * C<qadoh>
7976              
7977             Name: Qatar
7978              
7979             Time zone: C<Asia/Qatar>
7980              
7981             =item * C<rereu>
7982              
7983             Name: Réunion
7984              
7985             Time zone: C<Indian/Reunion>
7986              
7987             =item * C<robuh>
7988              
7989             Name: Bucharest, Romania
7990              
7991             Time zone: C<Europe/Bucharest>
7992              
7993             =item * C<rsbeg>
7994              
7995             Name: Belgrade, Serbia
7996              
7997             Time zone: C<Europe/Belgrade>
7998              
7999             =item * C<ruasf>
8000              
8001             Name: Astrakhan, Russia
8002              
8003             Time zone: C<Europe/Astrakhan>
8004              
8005             =item * C<rubax>
8006              
8007             Name: Barnaul, Russia
8008              
8009             Time zone: C<Asia/Barnaul>
8010              
8011             =item * C<ruchita>
8012              
8013             Name: Chita Zabaykalsky, Russia
8014              
8015             Time zone: C<Asia/Chita>
8016              
8017             =item * C<rudyr>
8018              
8019             Name: Anadyr, Russia
8020              
8021             Time zone: C<Asia/Anadyr>
8022              
8023             =item * C<rugdx>
8024              
8025             Name: Magadan, Russia
8026              
8027             Time zone: C<Asia/Magadan>
8028              
8029             =item * C<ruikt>
8030              
8031             Name: Irkutsk, Russia
8032              
8033             Time zone: C<Asia/Irkutsk>
8034              
8035             =item * C<rukgd>
8036              
8037             Name: Kaliningrad, Russia
8038              
8039             Time zone: C<Europe/Kaliningrad>
8040              
8041             =item * C<rukhndg>
8042              
8043             Name: Khandyga Tomponsky, Russia
8044              
8045             Time zone: C<Asia/Khandyga>
8046              
8047             =item * C<rukra>
8048              
8049             Name: Krasnoyarsk, Russia
8050              
8051             Time zone: C<Asia/Krasnoyarsk>
8052              
8053             =item * C<rukuf>
8054              
8055             Name: Samara, Russia
8056              
8057             Time zone: C<Europe/Samara>
8058              
8059             =item * C<rukvx>
8060              
8061             Name: Kirov, Russia
8062              
8063             Time zone: C<Europe/Kirov>
8064              
8065             =item * C<rumow>
8066              
8067             Name: Moscow, Russia
8068              
8069             Time zone: C<Europe/Moscow>, C<W-SU>
8070              
8071             =item * C<runoz>
8072              
8073             Name: Novokuznetsk, Russia
8074              
8075             Time zone: C<Asia/Novokuznetsk>
8076              
8077             =item * C<ruoms>
8078              
8079             Name: Omsk, Russia
8080              
8081             Time zone: C<Asia/Omsk>
8082              
8083             =item * C<ruovb>
8084              
8085             Name: Novosibirsk, Russia
8086              
8087             Time zone: C<Asia/Novosibirsk>
8088              
8089             =item * C<rupkc>
8090              
8091             Name: Kamchatka Peninsula, Russia
8092              
8093             Time zone: C<Asia/Kamchatka>
8094              
8095             =item * C<rurtw>
8096              
8097             Name: Saratov, Russia
8098              
8099             Time zone: C<Europe/Saratov>
8100              
8101             =item * C<rusred>
8102              
8103             Name: Srednekolymsk, Russia
8104              
8105             Time zone: C<Asia/Srednekolymsk>
8106              
8107             =item * C<rutof>
8108              
8109             Name: Tomsk, Russia
8110              
8111             Time zone: C<Asia/Tomsk>
8112              
8113             =item * C<ruuly>
8114              
8115             Name: Ulyanovsk, Russia
8116              
8117             Time zone: C<Europe/Ulyanovsk>
8118              
8119             =item * C<ruunera>
8120              
8121             Name: Ust-Nera Oymyakonsky, Russia
8122              
8123             Time zone: C<Asia/Ust-Nera>
8124              
8125             =item * C<ruuus>
8126              
8127             Name: Sakhalin, Russia
8128              
8129             Time zone: C<Asia/Sakhalin>
8130              
8131             =item * C<ruvog>
8132              
8133             Name: Volgograd, Russia
8134              
8135             Time zone: C<Europe/Volgograd>
8136              
8137             =item * C<ruvvo>
8138              
8139             Name: Vladivostok, Russia
8140              
8141             Time zone: C<Asia/Vladivostok>
8142              
8143             =item * C<ruyek>
8144              
8145             Name: Yekaterinburg, Russia
8146              
8147             Time zone: C<Asia/Yekaterinburg>
8148              
8149             =item * C<ruyks>
8150              
8151             Name: Yakutsk, Russia
8152              
8153             Time zone: C<Asia/Yakutsk>
8154              
8155             =item * C<rwkgl>
8156              
8157             Name: Kigali, Rwanda
8158              
8159             Time zone: C<Africa/Kigali>
8160              
8161             =item * C<saruh>
8162              
8163             Name: Riyadh, Saudi Arabia
8164              
8165             Time zone: C<Asia/Riyadh>
8166              
8167             =item * C<sbhir>
8168              
8169             Name: Guadalcanal, Solomon Islands
8170              
8171             Time zone: C<Pacific/Guadalcanal>
8172              
8173             =item * C<scmaw>
8174              
8175             Name: Mahé, Seychelles
8176              
8177             Time zone: C<Indian/Mahe>
8178              
8179             =item * C<sdkrt>
8180              
8181             Name: Khartoum, Sudan
8182              
8183             Time zone: C<Africa/Khartoum>
8184              
8185             =item * C<sesto>
8186              
8187             Name: Stockholm, Sweden
8188              
8189             Time zone: C<Europe/Stockholm>
8190              
8191             =item * C<sgsin>
8192              
8193             Name: Singapore
8194              
8195             Time zone: C<Asia/Singapore>, C<Singapore>
8196              
8197             =item * C<shshn>
8198              
8199             Name: Saint Helena
8200              
8201             Time zone: C<Atlantic/St_Helena>
8202              
8203             =item * C<silju>
8204              
8205             Name: Ljubljana, Slovenia
8206              
8207             Time zone: C<Europe/Ljubljana>
8208              
8209             =item * C<sjlyr>
8210              
8211             Name: Longyearbyen, Svalbard
8212              
8213             Time zone: C<Arctic/Longyearbyen>, C<Atlantic/Jan_Mayen>
8214              
8215             =item * C<skbts>
8216              
8217             Name: Bratislava, Slovakia
8218              
8219             Time zone: C<Europe/Bratislava>
8220              
8221             =item * C<slfna>
8222              
8223             Name: Freetown, Sierra Leone
8224              
8225             Time zone: C<Africa/Freetown>
8226              
8227             =item * C<smsai>
8228              
8229             Name: San Marino
8230              
8231             Time zone: C<Europe/San_Marino>
8232              
8233             =item * C<sndkr>
8234              
8235             Name: Dakar, Senegal
8236              
8237             Time zone: C<Africa/Dakar>
8238              
8239             =item * C<somgq>
8240              
8241             Name: Mogadishu, Somalia
8242              
8243             Time zone: C<Africa/Mogadishu>
8244              
8245             =item * C<srpbm>
8246              
8247             Name: Paramaribo, Suriname
8248              
8249             Time zone: C<America/Paramaribo>
8250              
8251             =item * C<ssjub>
8252              
8253             Name: Juba, South Sudan
8254              
8255             Time zone: C<Africa/Juba>
8256              
8257             =item * C<sttms>
8258              
8259             Name: São Tomé, São Tomé and Príncipe
8260              
8261             Time zone: C<Africa/Sao_Tome>
8262              
8263             =item * C<svsal>
8264              
8265             Name: El Salvador
8266              
8267             Time zone: C<America/El_Salvador>
8268              
8269             =item * C<sxphi>
8270              
8271             Name: Sint Maarten
8272              
8273             Time zone: C<America/Lower_Princes>
8274              
8275             =item * C<sydam>
8276              
8277             Name: Damascus, Syria
8278              
8279             Time zone: C<Asia/Damascus>
8280              
8281             =item * C<szqmn>
8282              
8283             Name: Mbabane, Swaziland
8284              
8285             Time zone: C<Africa/Mbabane>
8286              
8287             =item * C<tcgdt>
8288              
8289             Name: Grand Turk, Turks and Caicos Islands
8290              
8291             Time zone: C<America/Grand_Turk>
8292              
8293             =item * C<tdndj>
8294              
8295             Name: N'Djamena, Chad
8296              
8297             Time zone: C<Africa/Ndjamena>
8298              
8299             =item * C<tfpfr>
8300              
8301             Name: Kerguelen Islands, French Southern Territories
8302              
8303             Time zone: C<Indian/Kerguelen>
8304              
8305             =item * C<tglfw>
8306              
8307             Name: Lomé, Togo
8308              
8309             Time zone: C<Africa/Lome>
8310              
8311             =item * C<thbkk>
8312              
8313             Name: Bangkok, Thailand
8314              
8315             Time zone: C<Asia/Bangkok>
8316              
8317             =item * C<tjdyu>
8318              
8319             Name: Dushanbe, Tajikistan
8320              
8321             Time zone: C<Asia/Dushanbe>
8322              
8323             =item * C<tkfko>
8324              
8325             Name: Fakaofo, Tokelau
8326              
8327             Time zone: C<Pacific/Fakaofo>
8328              
8329             =item * C<tldil>
8330              
8331             Name: Dili, East Timor
8332              
8333             Time zone: C<Asia/Dili>
8334              
8335             =item * C<tmasb>
8336              
8337             Name: Ashgabat, Turkmenistan
8338              
8339             Time zone: C<Asia/Ashgabat>, C<Asia/Ashkhabad>
8340              
8341             =item * C<tntun>
8342              
8343             Name: Tunis, Tunisia
8344              
8345             Time zone: C<Africa/Tunis>
8346              
8347             =item * C<totbu>
8348              
8349             Name: Tongatapu, Tonga
8350              
8351             Time zone: C<Pacific/Tongatapu>
8352              
8353             =item * C<trist>
8354              
8355             Name: Istanbul, Türkiye
8356              
8357             Time zone: C<Europe/Istanbul>, C<Asia/Istanbul>, C<Turkey>
8358              
8359             =item * C<ttpos>
8360              
8361             Name: Port of Spain, Trinidad and Tobago
8362              
8363             Time zone: C<America/Port_of_Spain>
8364              
8365             =item * C<tvfun>
8366              
8367             Name: Funafuti, Tuvalu
8368              
8369             Time zone: C<Pacific/Funafuti>
8370              
8371             =item * C<twtpe>
8372              
8373             Name: Taipei, Taiwan
8374              
8375             Time zone: C<Asia/Taipei>, C<ROC>
8376              
8377             =item * C<tzdar>
8378              
8379             Name: Dar es Salaam, Tanzania
8380              
8381             Time zone: C<Africa/Dar_es_Salaam>
8382              
8383             =item * C<uaiev>
8384              
8385             Name: Kyiv, Ukraine
8386              
8387             Time zone: C<Europe/Kiev>, C<Europe/Kyiv>, C<Europe/Zaporozhye>, C<Europe/Uzhgorod>
8388              
8389             =item * C<uaozh>
8390              
8391             Zaporizhia (Zaporozhye), Ukraine
8392              
8393             Deprecated. See instead C<uaiev>
8394              
8395             =item * C<uasip>
8396              
8397             Name: Simferopol, Ukraine
8398              
8399             Time zone: C<Europe/Simferopol>
8400              
8401             =item * C<uauzh>
8402              
8403             Uzhhorod (Uzhgorod), Ukraine
8404              
8405             Deprecated. See instead C<uaiev>
8406              
8407             =item * C<ugkla>
8408              
8409             Name: Kampala, Uganda
8410              
8411             Time zone: C<Africa/Kampala>
8412              
8413             =item * C<umawk>
8414              
8415             Name: Wake Island, U.S. Minor Outlying Islands
8416              
8417             Time zone: C<Pacific/Wake>
8418              
8419             =item * C<umjon>
8420              
8421             Johnston Atoll, U.S. Minor Outlying Islands
8422              
8423             Deprecated. See instead C<ushnl>
8424              
8425             =item * C<ummdy>
8426              
8427             Name: Midway Islands, U.S. Minor Outlying Islands
8428              
8429             Time zone: C<Pacific/Midway>
8430              
8431             =item * C<unk>
8432              
8433             Name: Unknown time zone
8434              
8435             Time zone: C<Etc/Unknown>
8436              
8437             =item * C<usadk>
8438              
8439             Name: Adak (Alaska), United States
8440              
8441             Time zone: C<America/Adak>, C<America/Atka>, C<US/Aleutian>
8442              
8443             =item * C<usaeg>
8444              
8445             Name: Marengo (Indiana), United States
8446              
8447             Time zone: C<America/Indiana/Marengo>
8448              
8449             =item * C<usanc>
8450              
8451             Name: Anchorage, United States
8452              
8453             Time zone: C<America/Anchorage>, C<US/Alaska>
8454              
8455             =item * C<usboi>
8456              
8457             Name: Boise (Idaho), United States
8458              
8459             Time zone: C<America/Boise>
8460              
8461             =item * C<uschi>
8462              
8463             Name: Chicago, United States
8464              
8465             Time zone: C<America/Chicago>, C<US/Central>
8466              
8467             =item * C<usden>
8468              
8469             Name: Denver, United States
8470              
8471             Time zone: C<America/Denver>, C<America/Shiprock>, C<Navajo>, C<US/Mountain>
8472              
8473             =item * C<usdet>
8474              
8475             Name: Detroit, United States
8476              
8477             Time zone: C<America/Detroit>, C<US/Michigan>
8478              
8479             =item * C<ushnl>
8480              
8481             Name: Honolulu, United States
8482              
8483             Time zone: C<Pacific/Honolulu>, C<US/Hawaii>, C<Pacific/Johnston>
8484              
8485             =item * C<usind>
8486              
8487             Name: Indianapolis, United States
8488              
8489             Time zone: C<America/Indianapolis>, C<America/Fort_Wayne>, C<America/Indiana/Indianapolis>, C<US/East-Indiana>
8490              
8491             =item * C<usinvev>
8492              
8493             Name: Vevay (Indiana), United States
8494              
8495             Time zone: C<America/Indiana/Vevay>
8496              
8497             =item * C<usjnu>
8498              
8499             Name: Juneau (Alaska), United States
8500              
8501             Time zone: C<America/Juneau>
8502              
8503             =item * C<usknx>
8504              
8505             Name: Knox (Indiana), United States
8506              
8507             Time zone: C<America/Indiana/Knox>, C<America/Knox_IN>, C<US/Indiana-Starke>
8508              
8509             =item * C<uslax>
8510              
8511             Name: Los Angeles, United States
8512              
8513             Time zone: C<America/Los_Angeles>, C<US/Pacific>, C<US/Pacific-New>
8514              
8515             =item * C<uslui>
8516              
8517             Name: Louisville (Kentucky), United States
8518              
8519             Time zone: C<America/Louisville>, C<America/Kentucky/Louisville>
8520              
8521             =item * C<usmnm>
8522              
8523             Name: Menominee (Michigan), United States
8524              
8525             Time zone: C<America/Menominee>
8526              
8527             =item * C<usmtm>
8528              
8529             Name: Metlakatla (Alaska), United States
8530              
8531             Time zone: C<America/Metlakatla>
8532              
8533             =item * C<usmoc>
8534              
8535             Name: Monticello (Kentucky), United States
8536              
8537             Time zone: C<America/Kentucky/Monticello>
8538              
8539             =item * C<usnavajo>
8540              
8541             Shiprock (Navajo), United States
8542              
8543             Deprecated. See instead C<usden>
8544              
8545             =item * C<usndcnt>
8546              
8547             Name: Center (North Dakota), United States
8548              
8549             Time zone: C<America/North_Dakota/Center>
8550              
8551             =item * C<usndnsl>
8552              
8553             Name: New Salem (North Dakota), United States
8554              
8555             Time zone: C<America/North_Dakota/New_Salem>
8556              
8557             =item * C<usnyc>
8558              
8559             Name: New York, United States
8560              
8561             Time zone: C<America/New_York>, C<US/Eastern>
8562              
8563             =item * C<usoea>
8564              
8565             Name: Vincennes (Indiana), United States
8566              
8567             Time zone: C<America/Indiana/Vincennes>
8568              
8569             =item * C<usome>
8570              
8571             Name: Nome (Alaska), United States
8572              
8573             Time zone: C<America/Nome>
8574              
8575             =item * C<usphx>
8576              
8577             Name: Phoenix, United States
8578              
8579             Time zone: C<America/Phoenix>, C<US/Arizona>
8580              
8581             =item * C<ussit>
8582              
8583             Name: Sitka (Alaska), United States
8584              
8585             Time zone: C<America/Sitka>
8586              
8587             =item * C<ustel>
8588              
8589             Name: Tell City (Indiana), United States
8590              
8591             Time zone: C<America/Indiana/Tell_City>
8592              
8593             =item * C<uswlz>
8594              
8595             Name: Winamac (Indiana), United States
8596              
8597             Time zone: C<America/Indiana/Winamac>
8598              
8599             =item * C<uswsq>
8600              
8601             Name: Petersburg (Indiana), United States
8602              
8603             Time zone: C<America/Indiana/Petersburg>
8604              
8605             =item * C<usxul>
8606              
8607             Name: Beulah (North Dakota), United States
8608              
8609             Time zone: C<America/North_Dakota/Beulah>
8610              
8611             =item * C<usyak>
8612              
8613             Name: Yakutat (Alaska), United States
8614              
8615             Time zone: C<America/Yakutat>
8616              
8617             =item * C<utc>
8618              
8619             Name: UTC (Coordinated Universal Time)
8620              
8621             Time zone: C<Etc/UTC>, C<Etc/UCT>, C<Etc/Universal>, C<Etc/Zulu>, C<UCT>, C<UTC>, C<Universal>, C<Zulu>
8622              
8623             =item * C<utce01>
8624              
8625             Name: 1 hour ahead of UTC
8626              
8627             Time zone: C<Etc/GMT-1>
8628              
8629             =item * C<utce02>
8630              
8631             Name: 2 hours ahead of UTC
8632              
8633             Time zone: C<Etc/GMT-2>
8634              
8635             =item * C<utce03>
8636              
8637             Name: 3 hours ahead of UTC
8638              
8639             Time zone: C<Etc/GMT-3>
8640              
8641             =item * C<utce04>
8642              
8643             Name: 4 hours ahead of UTC
8644              
8645             Time zone: C<Etc/GMT-4>
8646              
8647             =item * C<utce05>
8648              
8649             Name: 5 hours ahead of UTC
8650              
8651             Time zone: C<Etc/GMT-5>
8652              
8653             =item * C<utce06>
8654              
8655             Name: 6 hours ahead of UTC
8656              
8657             Time zone: C<Etc/GMT-6>
8658              
8659             =item * C<utce07>
8660              
8661             Name: 7 hours ahead of UTC
8662              
8663             Time zone: C<Etc/GMT-7>
8664              
8665             =item * C<utce08>
8666              
8667             Name: 8 hours ahead of UTC
8668              
8669             Time zone: C<Etc/GMT-8>
8670              
8671             =item * C<utce09>
8672              
8673             Name: 9 hours ahead of UTC
8674              
8675             Time zone: C<Etc/GMT-9>
8676              
8677             =item * C<utce10>
8678              
8679             Name: 10 hours ahead of UTC
8680              
8681             Time zone: C<Etc/GMT-10>
8682              
8683             =item * C<utce11>
8684              
8685             Name: 11 hours ahead of UTC
8686              
8687             Time zone: C<Etc/GMT-11>
8688              
8689             =item * C<utce12>
8690              
8691             Name: 12 hours ahead of UTC
8692              
8693             Time zone: C<Etc/GMT-12>
8694              
8695             =item * C<utce13>
8696              
8697             Name: 13 hours ahead of UTC
8698              
8699             Time zone: C<Etc/GMT-13>
8700              
8701             =item * C<utce14>
8702              
8703             Name: 14 hours ahead of UTC
8704              
8705             Time zone: C<Etc/GMT-14>
8706              
8707             =item * C<utcw01>
8708              
8709             Name: 1 hour behind UTC
8710              
8711             Time zone: C<Etc/GMT+1>
8712              
8713             =item * C<utcw02>
8714              
8715             Name: 2 hours behind UTC
8716              
8717             Time zone: C<Etc/GMT+2>
8718              
8719             =item * C<utcw03>
8720              
8721             Name: 3 hours behind UTC
8722              
8723             Time zone: C<Etc/GMT+3>
8724              
8725             =item * C<utcw04>
8726              
8727             Name: 4 hours behind UTC
8728              
8729             Time zone: C<Etc/GMT+4>
8730              
8731             =item * C<utcw05>
8732              
8733             Name: 5 hours behind UTC
8734              
8735             Time zone: C<Etc/GMT+5>, C<EST>
8736              
8737             =item * C<utcw06>
8738              
8739             Name: 6 hours behind UTC
8740              
8741             Time zone: C<Etc/GMT+6>
8742              
8743             =item * C<utcw07>
8744              
8745             Name: 7 hours behind UTC
8746              
8747             Time zone: C<Etc/GMT+7>, C<MST>
8748              
8749             =item * C<utcw08>
8750              
8751             Name: 8 hours behind UTC
8752              
8753             Time zone: C<Etc/GMT+8>
8754              
8755             =item * C<utcw09>
8756              
8757             Name: 9 hours behind UTC
8758              
8759             Time zone: C<Etc/GMT+9>
8760              
8761             =item * C<utcw10>
8762              
8763             Name: 10 hours behind UTC
8764              
8765             Time zone: C<Etc/GMT+10>, C<HST>
8766              
8767             =item * C<utcw11>
8768              
8769             Name: 11 hours behind UTC
8770              
8771             Time zone: C<Etc/GMT+11>
8772              
8773             =item * C<utcw12>
8774              
8775             Name: 12 hours behind UTC
8776              
8777             Time zone: C<Etc/GMT+12>
8778              
8779             =item * C<uymvd>
8780              
8781             Name: Montevideo, Uruguay
8782              
8783             Time zone: C<America/Montevideo>
8784              
8785             =item * C<uzskd>
8786              
8787             Name: Samarkand, Uzbekistan
8788              
8789             Time zone: C<Asia/Samarkand>
8790              
8791             =item * C<uztas>
8792              
8793             Name: Tashkent, Uzbekistan
8794              
8795             Time zone: C<Asia/Tashkent>
8796              
8797             =item * C<vavat>
8798              
8799             Name: Vatican City
8800              
8801             Time zone: C<Europe/Vatican>
8802              
8803             =item * C<vcsvd>
8804              
8805             Name: Saint Vincent, Saint Vincent and the Grenadines
8806              
8807             Time zone: C<America/St_Vincent>
8808              
8809             =item * C<veccs>
8810              
8811             Name: Caracas, Venezuela
8812              
8813             Time zone: C<America/Caracas>
8814              
8815             =item * C<vgtov>
8816              
8817             Name: Tortola, British Virgin Islands
8818              
8819             Time zone: C<America/Tortola>
8820              
8821             =item * C<vistt>
8822              
8823             Name: Saint Thomas, U.S. Virgin Islands
8824              
8825             Time zone: C<America/St_Thomas>, C<America/Virgin>
8826              
8827             =item * C<vnsgn>
8828              
8829             Name: Ho Chi Minh City, Vietnam
8830              
8831             Time zone: C<Asia/Saigon>, C<Asia/Ho_Chi_Minh>
8832              
8833             =item * C<vuvli>
8834              
8835             Name: Efate, Vanuatu
8836              
8837             Time zone: C<Pacific/Efate>
8838              
8839             =item * C<wfmau>
8840              
8841             Name: Wallis Islands, Wallis and Futuna
8842              
8843             Time zone: C<Pacific/Wallis>
8844              
8845             =item * C<wsapw>
8846              
8847             Name: Apia, Samoa
8848              
8849             Time zone: C<Pacific/Apia>
8850              
8851             =item * C<yeade>
8852              
8853             Name: Aden, Yemen
8854              
8855             Time zone: C<Asia/Aden>
8856              
8857             =item * C<ytmam>
8858              
8859             Name: Mayotte
8860              
8861             Time zone: C<Indian/Mayotte>
8862              
8863             =item * C<zajnb>
8864              
8865             Name: Johannesburg, South Africa
8866              
8867             Time zone: C<Africa/Johannesburg>
8868              
8869             =item * C<zmlun>
8870              
8871             Name: Lusaka, Zambia
8872              
8873             Time zone: C<Africa/Lusaka>
8874              
8875             =item * C<zwhre>
8876              
8877             Name: Harare, Zimbabwe
8878              
8879             Time zone: C<Africa/Harare>
8880              
8881             =back
8882              
8883             See the L<standard documentation|https://unicode.org/reports/tr35/#Time_Zone_Identifiers> for more information.
8884              
8885             =item * C<va>
8886              
8887             A L<Unicode Variant Identifier|https://unicode.org/reports/tr35/#UnicodeVariantIdentifier> defines a special variant used for locales.
8888              
8889             =back
8890              
8891             =head2 Transform extensions
8892              
8893             This is used for transliterations, transcriptions, translations, etc, as per L<RFC6497|https://datatracker.ietf.org/doc/html/rfc6497>
8894              
8895             For example:
8896              
8897             =over 4
8898              
8899             =item * C<ja-t-it>
8900              
8901             The content is Japanese, transformed from Italian.
8902              
8903             =item * C<ja-Kana-t-it>
8904              
8905             The content is Japanese Katakana, transformed from Italian.
8906              
8907             =item * C<und-Latn-t-und-cyrl>
8908              
8909             The content is in the Latin script, transformed from the Cyrillic script.
8910              
8911             =item * C<und-Cyrl-t-und-latn-m0-ungegn-2007>
8912              
8913             The content is in Cyrillic, transformed from Latin, according to a UNGEGN specification dated 2007.
8914              
8915             The date is of format C<YYYYMMDD> all without space, and the month and day information should be provided only when necessary for clarification, as per the L<RFC6497, section 2.5(c)|https://datatracker.ietf.org/doc/html/rfc6497#section-2.5>
8916              
8917             =item * C<und-Cyrl-t-und-latn-m0-ungegn>
8918              
8919             Same, but without year.
8920              
8921             =back
8922              
8923             The complete list of valid subtags is as follows. They are all two to eight alphanumeric characters.
8924              
8925             =over 4
8926              
8927             =item * C<d0>
8928              
8929             Transform destination: for non-languages/scripts, such as fullwidth-halfwidth conversion
8930              
8931             See also C<s0>
8932              
8933             Possible L<values|https://github.com/unicode-org/cldr/blob/maint/maint-41/common/bcp47/transform-destination.xml> are:
8934              
8935             =over 8
8936              
8937             =item * C<accents>
8938              
8939             Map base + punctuation, etc to accented characters
8940              
8941             =item * C<ascii>
8942              
8943             Map as many characters to the closest ASCII character as possible
8944              
8945             =item * C<casefold>
8946              
8947             Apply Unicode case folding
8948              
8949             =item * C<charname>
8950              
8951             Map each character to its Unicode name
8952              
8953             =item * C<digit>
8954              
8955             Convert to digit form of accent
8956              
8957             =item * C<fcc>
8958              
8959             Map string to the FCC format; L<http://unicode.org/notes/tn5>
8960              
8961             =item * C<fcd>
8962              
8963             Map string to the FCD format; L<http://unicode.org/notes/tn5>
8964              
8965             =item * C<fwidth>
8966              
8967             Map characters to their fullwidth equivalents
8968              
8969             =item * C<hex>
8970              
8971             Map characters to a hex equivalents, eg C<a> to C<\u0061>; for hex variants see L<transform.xml|https://github.com/unicode-org/cldr/blob/maint/maint-41/common/bcp47/transform.xml>
8972              
8973             =item * C<hwidth>
8974              
8975             Map characters to their halfwidth equivalents
8976              
8977             =item * C<lower>
8978              
8979             Apply Unicode full lowercase mapping
8980              
8981             =item * C<morse>
8982              
8983             Map Unicode to Morse Code encoding
8984              
8985             =item * C<nfc>
8986              
8987             Map string to the Unicode NFC format
8988              
8989             =item * C<nfd>
8990              
8991             Map string to the Unicode NFD format
8992              
8993             =item * C<nfkc>
8994              
8995             Map string to the Unicode NFKC format
8996              
8997             =item * C<nfkd>
8998              
8999             Map string to the Unicode NFKD format
9000              
9001             =item * C<npinyin>
9002              
9003             Map pinyin written with tones to the numeric form
9004              
9005             =item * C<null>
9006              
9007             Make no change in the string
9008              
9009             =item * C<publish>
9010              
9011             Map to preferred forms for publishing, such as C<, >, C<—>
9012              
9013             =item * C<remove>
9014              
9015             Remove every character in the string
9016              
9017             =item * C<title>
9018              
9019             Apply Unicode full titlecase mapping
9020              
9021             =item * C<upper>
9022              
9023             Apply Unicode full uppercase mapping
9024              
9025             =item * C<zawgyi>
9026              
9027             Map Unicode to Zawgyi Myanmar encoding
9028              
9029             =back
9030              
9031             =item * C<h0>
9032              
9033             Hybrid Locale Identifiers: C<h0> with the value C<hybrid> indicates that the C<-t-> value is a language that is mixed into the main language tag to form a hybrid.
9034              
9035             For L<example|https://unicode.org/reports/tr35/#Hybrid_Locale>:
9036              
9037             =over 8
9038              
9039             =item * C<hi-t-en-h0-hybrid>
9040              
9041             Hybrid Deva - Hinglish
9042              
9043             Hindi-English hybrid where the script is Devanagari*
9044              
9045             =item * C<hi-Latn-t-en-h0-hybrid>
9046              
9047             Hybrid Latin - Hinglish
9048              
9049             Hindi-English hybrid where the script is Latin*
9050              
9051             =item * C<ru-t-en-h0-hybrid>
9052              
9053             Hybrid Cyrillic - Runglish
9054              
9055             Russian with an admixture of American English
9056              
9057             =item * C<ru-t-en-gb-h0-hybrid>
9058              
9059             Hybrid Cyrillic - Runglish
9060              
9061             Russian with an admixture of British English
9062              
9063             =item * C<en-t-zh-h0-hybrid>
9064              
9065             Hybrid Latin - Chinglish
9066              
9067             American English with an admixture of Chinese (Simplified Mandarin Chinese)
9068              
9069             =item * C<en-t-zh-hant-h0-hybrid>
9070              
9071             Hybrid Latin - Chinglish
9072              
9073             American English with an admixture of Chinese (Traditional Mandarin Chinese)
9074              
9075             =back
9076              
9077             =item * C<i0>
9078              
9079             Input Method Engine transform: used to indicate an input method transformation, such as one used by a client-side input method. The first subfield in a sequence would typically be a C<platform> or vendor designation.
9080              
9081             For example: C<zh-t-i0-pinyin>
9082              
9083             Possible L<values|https://github.com/unicode-org/cldr/blob/maint/maint-41/common/bcp47/transform_ime.xml> are:
9084              
9085             =over 8
9086              
9087             =item * C<handwrit>
9088              
9089             Handwriting input: used when the only information known (or requested) is that the text was (or is to be) converted using an handwriting input.
9090              
9091             =item * C<pinyin>
9092              
9093             Pinyin input: for simplified Chinese characters. See also L<http://en.wikipedia.org/wiki/Pinyin_method>.
9094              
9095             =item * C<und>
9096              
9097             The choice of input method is not specified. Used when the only information known (or requested) is that the text was (or is to be) converted using an input method engine
9098              
9099             =item * C<wubi>
9100              
9101             Wubi input: for simplified Chinese characters. For background information, see L<http://en.wikipedia.org/wiki/Wubi_method>
9102              
9103             =back
9104              
9105             =item * C<k0>
9106              
9107             Keyboard transform: used to indicate a keyboard transformation, such as one used by a client-side virtual keyboard. The first subfield in a sequence would typically be a C<platform> designation, representing the platform that the keyboard is intended for.
9108              
9109             For example: C<en-t-k0-dvorak>
9110              
9111             Possible L<values|https://github.com/unicode-org/cldr/blob/maint/maint-41/common/bcp47/transform_keyboard.xml> are:
9112              
9113             =over 8
9114              
9115             =item * C<101key>
9116              
9117             101 key layout.
9118              
9119             =item * C<102key>
9120              
9121             102 key layout.
9122              
9123             =item * C<600dpi>
9124              
9125             Keyboard for a 600 dpi device.
9126              
9127             =item * C<768dpi>
9128              
9129             Keyboard for a 768 dpi device.
9130              
9131             =item * C<android>
9132              
9133             Android keyboard.
9134              
9135             =item * C<azerty>
9136              
9137             A AZERTY-based keyboard or one that approximates AZERTY in a different script.
9138              
9139             =item * C<chromeos>
9140              
9141             ChromeOS keyboard.
9142              
9143             =item * C<colemak>
9144              
9145             Colemak keyboard layout. The Colemak keyboard is an alternative to the QWERTY and dvorak keyboards. http://colemak.com/.
9146              
9147             =item * C<dvorak>
9148              
9149             Dvorak keyboard layout. See also L<http://en.wikipedia.org/wiki/Dvorak_Simplified_Keyboard>.
9150              
9151             =item * C<dvorakl>
9152              
9153             Dvorak left-handed keyboard layout. See also L<http://en.wikipedia.org/wiki/File:KB_Dvorak_Left.svg>.
9154              
9155             =item * C<dvorakr>
9156              
9157             Dvorak right-handed keyboard layout. See also L<http://en.wikipedia.org/wiki/File:KB_Dvorak_Right.svg>.
9158              
9159             =item * C<el220>
9160              
9161             Greek 220 keyboard. See also L<http://www.microsoft.com/resources/msdn/goglobal/keyboards/kbdhela2.html>.
9162              
9163             =item * C<el319>
9164              
9165             Greek 319 keyboard. See also L<ftp://ftp.software.ibm.com/software/globalization/keyboards/KBD319.pdf>.
9166              
9167             =item * C<extended>
9168              
9169             A keyboard that has been enhanced with a large number of extra characters.
9170              
9171             =item * C<googlevk>
9172              
9173             Google virtual keyboard.
9174              
9175             =item * C<isiri>
9176              
9177             Persian ISIRI keyboard. Based on ISIRI 2901:1994 standard. See also L<http://behdad.org/download/Publications/persiancomputing/a007.pdf>.
9178              
9179             =item * C<legacy>
9180              
9181             A keyboard that has been replaced with a newer standard but is kept for legacy purposes.
9182              
9183             =item * C<lt1205>
9184              
9185             Lithuanian standard keyboard, based on the LST 1205:1992 standard. See also L<http://www.kada.lt/litwin/>.
9186              
9187             =item * C<lt1582>
9188              
9189             Lithuanian standard keyboard, based on the LST 1582:2000 standard. See also L<http://www.kada.lt/litwin/>.
9190              
9191             =item * C<nutaaq>
9192              
9193             Inuktitut Nutaaq keyboard. See also L<http://www.pirurvik.ca/en/webfm_send/15>.
9194              
9195             =item * C<osx>
9196              
9197             Mac OSX keyboard.
9198              
9199             =item * C<patta>
9200              
9201             Thai Pattachote keyboard. This is a less frequently used layout in Thai (Kedmanee layout is more popular). See also L<http://www.nectec.or.th/it-standards/keyboard_layout/thai-key.htm>.
9202              
9203             =item * C<qwerty>
9204              
9205             QWERTY-based keyboard or one that approximates QWERTY in a different script.
9206              
9207             =item * C<qwertz>
9208              
9209             QWERTZ-based keyboard or one that approximates QWERTZ in a different script.
9210              
9211             =item * C<ta99>
9212              
9213             Tamil 99 keyboard. See also L<http://www.tamilvu.org/Tamilnet99/annex1.htm>.
9214              
9215             =item * C<und>
9216              
9217             The vender for the keyboard is not specified. Used when the only information known (or requested) is that the text was (or is to be) converted using an keyboard.
9218              
9219             =item * C<var>
9220              
9221             A keyboard layout with small variations from the default.
9222              
9223             =item * C<viqr>
9224              
9225             Vietnamese VIQR layout, based on L<http://tools.ietf.org/html/rfc1456>.
9226              
9227             =item * C<windows>
9228              
9229             Windows keyboard.
9230              
9231             =back
9232              
9233             =item * C<m0>
9234              
9235             Transform extension mechanism: to reference an authority or rules for a type of transformation.
9236              
9237             For example: C<und-Latn-t-ru-m0-ungegn-2007>
9238              
9239             Possible L<values|https://github.com/unicode-org/cldr/blob/maint/maint-41/common/bcp47/transform.xml> are:
9240              
9241             =over 8
9242              
9243             =item * C<aethiopi>
9244              
9245             Encylopedia Aethiopica Transliteration
9246              
9247             =item * C<alaloc>
9248              
9249             American Library Association-Library of Congress
9250              
9251             =item * C<betamets>
9252              
9253             Beta Maṣāḥǝft Transliteration
9254              
9255             =item * C<bgn>
9256              
9257             US Board on Geographic Names
9258              
9259             =item * C<buckwalt>
9260              
9261             Buckwalter Arabic transliteration system
9262              
9263             =item * C<c11>
9264              
9265             for hex transforms, using the C11 syntax: \u0061\U0001F4D6
9266              
9267             =item * C<css>
9268              
9269             for hex transforms, using the CSS syntax: \61 \01F4D6, spacing where necessary
9270              
9271             =item * C<din>
9272              
9273             Deutsches Institut für Normung
9274              
9275             =item * C<es3842>
9276              
9277             Ethiopian Standards Agency ES 3842:2014 Ethiopic-Latin Transliteration
9278              
9279             =item * C<ewts>
9280              
9281             Extended Wylie Transliteration Scheme
9282              
9283             =item * C<gost>
9284              
9285             Euro-Asian Council for Standardization, Metrology and Certification
9286              
9287             =item * C<gurage>
9288              
9289             Gurage Legacy to Modern Transliteration
9290              
9291             =item * C<gutgarts>
9292              
9293             Yaros Gutgarts Ethiopic-Cyrillic Transliteration
9294              
9295             =item * C<iast>
9296              
9297             International Alphabet of Sanskrit Transliteration
9298              
9299             =item * C<iesjes>
9300              
9301             IES/JES Amharic Transliteration
9302              
9303             =item * C<iso>
9304              
9305             International Organization for Standardization
9306              
9307             =item * C<java>
9308              
9309             for hex transforms, using the Java syntax: \u0061\uD83D\uDCD6
9310              
9311             =item * C<lambdin>
9312              
9313             Thomas Oden Lambdin Ethiopic-Latin Transliteration
9314              
9315             =item * C<mcst>
9316              
9317             Korean Ministry of Culture, Sports and Tourism
9318              
9319             =item * C<mns>
9320              
9321             Mongolian National Standard
9322              
9323             =item * C<percent>
9324              
9325             for hex transforms, using the percent syntax: %61%F0%9F%93%96
9326              
9327             =item * C<perl>
9328              
9329             for hex transforms, using the perl syntax: \x{61}\x{1F4D6}
9330              
9331             =item * C<plain>
9332              
9333             for hex transforms, with no surrounding syntax, spacing where necessary: 0061 1F4D6
9334              
9335             =item * C<prprname>
9336              
9337             transform variant for proper names
9338              
9339             =item * C<satts>
9340              
9341             Standard Arabic Technical Transliteration System (SATTS)
9342              
9343             =item * C<sera>
9344              
9345             System for Ethiopic Representation in ASCII
9346              
9347             =item * C<tekieali>
9348              
9349             Tekie Alibekit Blin-Latin Transliteration
9350              
9351             =item * C<ungegn>
9352              
9353             United Nations Group of Experts on Geographical Names
9354              
9355             =item * C<unicode>
9356              
9357             to hex with the Unicode syntax: U+0061 U+1F4D6, spacing where necessary
9358              
9359             =item * C<xaleget>
9360              
9361             Eritrean Ministry of Education Blin-Latin Transliteration
9362              
9363             =item * C<xml>
9364              
9365             for hex transforms, using the xml syntax: &#x61;&#x1F4D6;
9366              
9367             =item * C<xml10>
9368              
9369             for hex transforms, using the xml decimal syntax: &#97;&#128214;
9370              
9371             =back
9372              
9373             =item * C<s0>
9374              
9375             Transform source: for non-languages/scripts, such as fullwidth-halfwidth conversion
9376              
9377             See also C<d0>
9378              
9379             Possible L<values|https://github.com/unicode-org/cldr/blob/maint/maint-41/common/bcp47/transform-destination.xml> are:
9380              
9381             =over 8
9382              
9383             =item * C<accents>
9384              
9385             Accented characters to map base + punctuation, etc
9386              
9387             =item * C<ascii>
9388              
9389             Map from ASCII to the target, perhaps using different conventions
9390              
9391             =item * C<hex>
9392              
9393             Map characters from hex equivalents, trying all variants, eg C<U+0061> to C<a>; for hex variants see L<transform.xml|https://github.com/unicode-org/cldr/blob/maint/maint-41/common/bcp47/transform.xml>
9394              
9395             =item * C<morse>
9396              
9397             Map Morse Code to Unicode encoding
9398              
9399             =item * C<npinyin>
9400              
9401             Map the numeric form of pinyin to the tone format
9402              
9403             =item * C<publish>
9404              
9405             Map publishing characters, such as C<, >, C<—>, to from vanilla characters
9406              
9407             =item * C<zawgyi>
9408              
9409             Map Zawgyi Myanmar encoding to Unicode
9410              
9411             =back
9412              
9413             =item * C<t0>
9414              
9415             Machine Translation: used to indicate content that has been machine translated, or a request for a particular type of machine translation of content. The first subfield in a sequence would typically be a C<platform> or vendor designation.
9416              
9417             For example: C<ja-t-de-t0-und>
9418              
9419             =item * C<x0>
9420              
9421             Private Use.
9422              
9423             For example: C<ja-t-de-t0-und-x0-medical>
9424              
9425             =back
9426              
9427             =head2 Collation Options
9428              
9429             L<Parametric settings|https://unicode.org/reports/tr35/tr35-collation.html#Setting_Options> can be specified in language tags or in rule syntax (in the form [keyword value] ). For example, C<-ks-level2> or [strength 2] will only compare strings based on their primary and secondary weights.
9430              
9431             The options description below is taken from the LDML standard, and reflect how the algorithm works when implemented by web browser, or other runtime environment. This module does not do any of those algorithms. The documentation is only here for your benefit and convenience.
9432              
9433             See the L<standard documentation|https://unicode.org/reports/tr35/tr35-collation.html> and the L<DUCET (Default Unicode Collation Element Table)|https://www.unicode.org/reports/tr10/#Default_Unicode_Collation_Element_Table> for more information.
9434              
9435             =over 4
9436              
9437             =item * C<ka> or C<colAlternate>
9438              
9439             Sets alternate handling for variable weights.
9440              
9441             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L34> are optional and can be:
9442              
9443             =over 8
9444              
9445             =item * C<noignore> or C<non-ignorable>
9446              
9447             Default value.
9448              
9449             =item * C<shifted>
9450              
9451             =back
9452              
9453             =item * C<kb> or C<colBackwards>
9454              
9455             Sets collation parameter key for backward collation weight.
9456              
9457             Sets alternate handling for variable weights.
9458              
9459             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L39> are optional and can be: C<true> or C<yes>, C<false> (default) or C<no>
9460              
9461             =item * C<kc> or C<colCaseLevel>
9462              
9463             Sets collation parameter key for case level.
9464              
9465             Specifies a boolean. If C<on>, a level consisting only of case characteristics will be inserted in front of tertiary level, as a "Level 2.5". To ignore accents but take case into account, set strength to C<primary> and case level to C<on>.
9466              
9467             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L44> are optional and can be: C<true> or C<yes>, C<false> (default) or C<no>
9468              
9469             =item * C<kf> or C<colCaseFirst>
9470              
9471             Sets collation parameter key for ordering by case.
9472              
9473             If set to C<upper>, causes upper case to sort before lower case. If set to C<lower>, causes lower case to sort before upper case.
9474              
9475             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L49> are: C<upper>, C<lower>, C<false> (default) or C<no>
9476              
9477             =item * C<kh> or C<colHiraganaQuaternary>
9478              
9479             Sets collation parameter key for special Hiragana handling.
9480              
9481             This is deprecated by the LDML standard.
9482              
9483             Specifies a boolean. Controls special treatment of Hiragana code points on quaternary level. If turned on, Hiragana codepoints will get lower values than all the other non-variable code points in shifted.
9484              
9485             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L55> are optional and can be: C<true> (default) or C<yes>, C<false> or C<no>
9486              
9487             =item * C<kk> or C<colNormalization>
9488              
9489             Sets collation parameter key for normalisation.
9490              
9491             Specifies a boolean. If on, then the normal L<UCA|https://www.unicode.org/reports/tr41/#UTS10> algorithm is used.
9492              
9493             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L60> are optional and can be: C<true> (default) or C<yes>, C<false> or C<no>
9494              
9495             =item * C<kn> or C<colNumeric>
9496              
9497             Sets collation parameter key for numeric handling.
9498              
9499             Specifies a boolean. If set to on, any sequence of Decimal Digits is sorted at a primary level with its numeric value.
9500              
9501             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L65> are optional and can be: C<true> or C<yes>, C<false> (default) or C<no>
9502              
9503             =item * C<kr> or C<colReorder>
9504              
9505             Sets collation reorder codes.
9506              
9507             Specifies a reordering of scripts or other significant blocks of characters such as symbols, punctuation, and digits.
9508              
9509             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L70> are: C<currency>, C<digit>, C<punct>, C<space>, C<symbol>, or any BCP47 script ID.
9510              
9511             Also possible: C<others> where all codes not explicitly mentioned should be ordered. The script code Zzzz (Unknown Script) is a synonym for others.
9512              
9513             For example:
9514              
9515             =over 8
9516              
9517             =item * C<en-u-kr-latn-digit>
9518              
9519             Reorder digits after Latin characters.
9520              
9521             =item * C<en-u-kr-arab-cyrl-others-symbol>
9522              
9523             Reorder Arabic characters first, then Cyrillic, and put symbols at the end—after all other characters.
9524              
9525             =item * C<en-u-kr-others>
9526              
9527             Remove any locale-specific reordering, and use DUCET order for reordering blocks.
9528              
9529             =back
9530              
9531             =item * C<ks> or C<colStrength>
9532              
9533             Sets the collation parameter key for collation strength used for comparison.
9534              
9535             Possible L<values|https://github.com/unicode-org/cldr/blob/5ae2965c8afed18f89f54195db72205aa5b6fc3a/common/bcp47/collation.xml#L79> are:
9536              
9537             =over 8
9538              
9539             =item * C<level1> or C<primary>
9540              
9541             =item * C<level2> or C<secondary>
9542              
9543             =item * C<level3> (default) or C<tertiary>
9544              
9545             =item * C<level4> or C<quaternary> or C<quarternary>
9546              
9547             =item * C<identic> or C<identical>
9548              
9549             =back
9550              
9551             =item * C<kv>
9552              
9553             Sets the collation parameter key for C<maxVariable>, the last reordering group to be affected by C<ka-shifted>.
9554              
9555             Possible values are:
9556              
9557             =over 8
9558              
9559             =item * C<currency>
9560              
9561             Spaces, punctuation and all symbols are affected by ka-shifted.
9562              
9563             =item * C<punct>
9564              
9565             Spaces and punctuation are affected by ka-shifted (CLDR default).
9566              
9567             =item * C<space>
9568              
9569             Only spaces are affected by ka-shifted.
9570              
9571             =item * C<symbol>
9572              
9573             Spaces, punctuation and symbols except for currency symbols are affected by ka-shifted (UCA default).
9574              
9575             =back
9576              
9577             =item * C<vt>
9578              
9579             Sets the parameter key for the variable top.
9580              
9581             B<This is deprecated by the LDML standard.>
9582              
9583             =back
9584              
9585             =head1 EXCEPTIONS
9586              
9587             This module does not die upon errors, unless you have set L<fatal|/fatal> to a true value. Instead it sets an L<error object|Locale::Unicode::Exception> that can be retrieved.
9588              
9589             When an error occurred, an L<error object|Locale::Unicode::Exception> will be set and the method will return C<undef> in scalar context and an empty list in list context.
9590              
9591             Otherwise, the only occasions when this module will die is when there is an internal design error, which would be my fault.
9592              
9593             =head1 SERIALISATION
9594              
9595             C<Locale::Unicode> supports L<Storable::Improved>, L<Storable>, L<Sereal> and L<CBOR|CBOR::XS> serialisation, by implementing the methods C<FREEZE>, C<THAW>, C<STORABLE_freeze>, C<STORABLE_thaw>
9596              
9597             For serialisation with L<Sereal>, make sure to instantiate the L<Sereal encoder|Sereal::Encoder> with the C<freeze_callbacks> option set to true, otherwise, C<Sereal> will not use the C<FREEZE> and C<THAW> methods.
9598              
9599             See L<Sereal::Encoder/"FREEZE/THAW CALLBACK MECHANISM"> for more information.
9600              
9601             For L<CBOR|CBOR::XS>, it is recommended to use the option C<allow_sharing> to enable the reuse of references, such as:
9602              
9603             my $cbor = CBOR::XS->new->allow_sharing;
9604              
9605             Also, if you use the option C<allow_tags> with L<JSON>, then all of those modules will work too, since this option enables support for the C<FREEZE> and C<THAW> methods.
9606              
9607             =head1 AUTHOR
9608              
9609             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
9610              
9611             =head1 SEE ALSO
9612              
9613             L<https://github.com/unicode-org/cldr/tree/main/common/bcp47>, L<https://en.wikipedia.org/wiki/IETF_language_tag>
9614              
9615             L<https://www.rfc-editor.org/info/bcp47>
9616              
9617             L<Unicode Locale Data Markup Language|https://unicode.org/reports/tr35/>
9618              
9619             L<BCP47|https://www.rfc-editor.org/rfc/bcp/bcp47.txt>
9620              
9621             L<RFC6067 on the Unicode extensions|https://datatracker.ietf.org/doc/html/rfc6067>
9622              
9623             L<RFC6497 on the transformation extension|https://datatracker.ietf.org/doc/html/rfc6497>
9624              
9625             L<RFC5646|https://www.rfc-editor.org/rfc/rfc5646.html>
9626              
9627             See L<HTML::Object::Locale> for an implementation of Web API class L<Intl.Locale|https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale>
9628              
9629             L<Unicode::Collate>, L<Unicode::Collate::Locale>, L<Unicode::Unihan>
9630              
9631             L<Locale::Unicode::Data> for the entire C<CLDR> data accessible as a SQLite database.
9632              
9633             =head1 COPYRIGHT & LICENSE
9634              
9635             Copyright(c) 2024 DEGUEST Pte. Ltd.
9636              
9637             All rights reserved
9638              
9639             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
9640              
9641             =cut