File | /usr/local/lib/perl5/site_perl/5.10.1/DateTime/Locale.pm |
Statements Executed | 15226 |
Statement Execution Time | 51.9ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
466 | 1 | 1 | 17.7ms | 34.7ms | _register | DateTime::Locale::
1 | 1 | 1 | 8.89ms | 8.94ms | BEGIN@11 | DateTime::Locale::
1 | 1 | 1 | 3.12ms | 13.2ms | add_aliases | DateTime::Locale::
423 | 1 | 1 | 2.88ms | 10.1ms | _registered_id | DateTime::Locale::
1 | 1 | 1 | 2.53ms | 37.2ms | register | DateTime::Locale::
1 | 1 | 1 | 2.34ms | 3.12ms | BEGIN@10 | DateTime::Locale::
40 | 4 | 3 | 598µs | 5.57ms | load | DateTime::Locale::
2 | 1 | 1 | 324µs | 3.81ms | _load_class_from_id | DateTime::Locale::
466 | 1 | 2 | 294µs | 294µs | CORE:match (opcode) | DateTime::Locale::
1 | 1 | 1 | 36µs | 50.6ms | BEGIN@148 | DateTime::Locale::
1 | 1 | 1 | 35µs | 35µs | BEGIN@6 | DateTime::Locale::
1 | 1 | 1 | 14µs | 80µs | BEGIN@12 | DateTime::Locale::
1 | 1 | 1 | 14µs | 17µs | BEGIN@3 | DateTime::Locale::
1 | 1 | 1 | 7µs | 16µs | BEGIN@4 | DateTime::Locale::
0 | 0 | 0 | 0s | 0s | _guess_id | DateTime::Locale::
0 | 0 | 0 | 0s | 0s | _parse_id | DateTime::Locale::
0 | 0 | 0 | 0s | 0s | ids | DateTime::Locale::
0 | 0 | 0 | 0s | 0s | names | DateTime::Locale::
0 | 0 | 0 | 0s | 0s | native_names | DateTime::Locale::
0 | 0 | 0 | 0s | 0s | remove_alias | DateTime::Locale::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package DateTime::Locale; | ||||
2 | |||||
3 | 3 | 20µs | 2 | 20µs | # spent 17µs (14+3) within DateTime::Locale::BEGIN@3 which was called
# once (14µs+3µs) by DateTime::BEGIN@41 at line 3 # spent 17µs making 1 call to DateTime::Locale::BEGIN@3
# spent 3µs making 1 call to strict::import |
4 | 3 | 19µs | 2 | 25µs | # spent 16µs (7+9) within DateTime::Locale::BEGIN@4 which was called
# once (7µs+9µs) by DateTime::BEGIN@41 at line 4 # spent 16µs making 1 call to DateTime::Locale::BEGIN@4
# spent 9µs making 1 call to warnings::import |
5 | |||||
6 | 3 | 52µs | 1 | 35µs | # spent 35µs within DateTime::Locale::BEGIN@6 which was called
# once (35µs+0s) by DateTime::BEGIN@41 at line 6 # spent 35µs making 1 call to DateTime::Locale::BEGIN@6 |
7 | |||||
8 | # Loading this here isn't necessary, but it makes it easier to catch | ||||
9 | # syntax errors when testing. | ||||
10 | 3 | 109µs | 1 | 3.12ms | # spent 3.12ms (2.34+784µs) within DateTime::Locale::BEGIN@10 which was called
# once (2.34ms+784µs) by DateTime::BEGIN@41 at line 10 # spent 3.12ms making 1 call to DateTime::Locale::BEGIN@10 |
11 | 3 | 144µs | 1 | 8.94ms | # spent 8.94ms (8.89+52µs) within DateTime::Locale::BEGIN@11 which was called
# once (8.89ms+52µs) by DateTime::BEGIN@41 at line 11 # spent 8.94ms making 1 call to DateTime::Locale::BEGIN@11 |
12 | 3 | 433µs | 2 | 146µs | # spent 80µs (14+66) within DateTime::Locale::BEGIN@12 which was called
# once (14µs+66µs) by DateTime::BEGIN@41 at line 12 # spent 80µs making 1 call to DateTime::Locale::BEGIN@12
# spent 66µs making 1 call to Exporter::import |
13 | |||||
14 | 1 | 900ns | our $VERSION = '0.44'; | ||
15 | |||||
16 | |||||
17 | 1 | 200ns | my %Class; | ||
18 | 1 | 0s | my %DataForID; | ||
19 | 1 | 0s | my %NameToID; | ||
20 | 1 | 0s | my %NativeNameToID; | ||
21 | 1 | 0s | my %AliasToID; | ||
22 | 1 | 0s | my %IDToExtra; | ||
23 | |||||
24 | 1 | 0s | my %LoadCache; | ||
25 | |||||
26 | sub register | ||||
27 | # spent 37.2ms (2.53+34.7) within DateTime::Locale::register which was called
# once (2.53ms+34.7ms) by DateTime::Locale::BEGIN@148 at line 149 | ||||
28 | 3 | 1.96ms | my $class = shift; | ||
29 | |||||
30 | %LoadCache = (); | ||||
31 | |||||
32 | if ( ref $_[0] ) # spent 34.7ms making 466 calls to DateTime::Locale::_register, avg 74µs/call | ||||
33 | { | ||||
34 | $class->_register(%$_) foreach @_; | ||||
35 | } | ||||
36 | else | ||||
37 | { | ||||
38 | $class->_register(@_); | ||||
39 | } | ||||
40 | } | ||||
41 | |||||
42 | sub _register | ||||
43 | # spent 34.7ms (17.7+17.0) within DateTime::Locale::_register which was called 466 times, avg 74µs/call:
# 466 times (17.7ms+17.0ms) by DateTime::Locale::register at line 32, avg 74µs/call | ||||
44 | 10718 | 16.5ms | my $class = shift; | ||
45 | |||||
46 | 1 | 17.4ms | 466 | 16.7ms | my %p = validate( @_, # spent 16.7ms making 466 calls to Params::Validate::_validate, avg 36µs/call |
47 | { id => { type => SCALAR }, | ||||
48 | |||||
49 | en_language => { type => SCALAR }, | ||||
50 | en_script => { type => SCALAR, optional => 1 }, | ||||
51 | en_territory => { type => SCALAR, optional => 1 }, | ||||
52 | en_variant => { type => SCALAR, optional => 1 }, | ||||
53 | |||||
54 | native_language => { type => SCALAR, optional => 1 }, | ||||
55 | native_script => { type => SCALAR, optional => 1 }, | ||||
56 | native_territory => { type => SCALAR, optional => 1 }, | ||||
57 | native_variant => { type => SCALAR, optional => 1 }, | ||||
58 | |||||
59 | class => { type => SCALAR, optional => 1 }, | ||||
60 | replace => { type => SCALAR, default => 0 }, | ||||
61 | } ); | ||||
62 | |||||
63 | my $id = $p{id}; | ||||
64 | |||||
65 | die "'\@' or '=' are not allowed in locale ids" # spent 294µs making 466 calls to DateTime::Locale::CORE:match, avg 630ns/call | ||||
66 | if $id =~ /[\@=]/; | ||||
67 | |||||
68 | die "You cannot replace an existing locale ('$id') unless you also specify the 'replace' parameter as true\n" | ||||
69 | if ! delete $p{replace} && exists $DataForID{$id}; | ||||
70 | |||||
71 | $p{native_language} = $p{en_language} | ||||
72 | unless exists $p{native_language}; | ||||
73 | |||||
74 | my @en_pieces; | ||||
75 | my @native_pieces; | ||||
76 | foreach my $p ( qw( language script territory variant ) ) | ||||
77 | { | ||||
78 | push @en_pieces, $p{"en_$p"} if exists $p{"en_$p"}; | ||||
79 | push @native_pieces, $p{"native_$p"} if exists $p{"native_$p"}; | ||||
80 | } | ||||
81 | |||||
82 | $p{en_complete_name} = join ' ', @en_pieces; | ||||
83 | $p{native_complete_name} = join ' ', @native_pieces; | ||||
84 | |||||
85 | $DataForID{$id} = \%p; | ||||
86 | |||||
87 | $NameToID{ $p{en_complete_name} } = $id; | ||||
88 | $NativeNameToID{ $p{native_complete_name} } = $id; | ||||
89 | |||||
90 | $Class{$id} = $p{class} if defined exists $p{class}; | ||||
91 | } | ||||
92 | |||||
93 | sub _registered_id | ||||
94 | # spent 10.1ms (2.88+7.21) within DateTime::Locale::_registered_id which was called 423 times, avg 24µs/call:
# 423 times (2.88ms+7.21ms) by DateTime::Locale::add_aliases at line 114, avg 24µs/call | ||||
95 | 1692 | 5.72ms | shift; | ||
96 | 1 | 4.57ms | 423 | 7.21ms | my ($id) = validate_pos( @_, { type => SCALAR } ); # spent 7.21ms making 423 calls to Params::Validate::_validate_pos, avg 17µs/call |
97 | |||||
98 | return 1 if $AliasToID{$id}; | ||||
99 | return 1 if $DataForID{$id}; | ||||
100 | |||||
101 | return 0; | ||||
102 | } | ||||
103 | |||||
104 | sub add_aliases | ||||
105 | # spent 13.2ms (3.12+10.1) within DateTime::Locale::add_aliases which was called
# once (3.12ms+10.1ms) by DateTime::Locale::BEGIN@148 at line 150 | ||||
106 | 2542 | 2.27ms | shift; | ||
107 | |||||
108 | %LoadCache = (); | ||||
109 | |||||
110 | my $aliases = ref $_[0] ? $_[0] : {@_}; | ||||
111 | |||||
112 | while ( my ( $alias, $id ) = each %$aliases ) | ||||
113 | { | ||||
114 | die "Unregistered locale '$id' cannot be used as an alias target for $alias" # spent 10.1ms making 423 calls to DateTime::Locale::_registered_id, avg 24µs/call | ||||
115 | unless __PACKAGE__->_registered_id($id); | ||||
116 | |||||
117 | die "Can't alias an id to itself" | ||||
118 | if $alias eq $id; | ||||
119 | |||||
120 | # check for overwrite? | ||||
121 | |||||
122 | my %seen = ( $alias => 1, $id => 1 ); | ||||
123 | my $copy = $id; | ||||
124 | while ( $copy = $AliasToID{$copy} ) | ||||
125 | { | ||||
126 | die "Creating an alias from $alias to $id would create a loop.\n" | ||||
127 | if $seen{$copy}; | ||||
128 | |||||
129 | $seen{$copy} = 1; | ||||
130 | } | ||||
131 | |||||
132 | $AliasToID{$alias} = $id; | ||||
133 | } | ||||
134 | } | ||||
135 | |||||
136 | sub remove_alias | ||||
137 | { | ||||
138 | shift; | ||||
139 | |||||
140 | %LoadCache = (); | ||||
141 | |||||
142 | my ($alias) = validate_pos( @_, { type => SCALAR } ); | ||||
143 | |||||
144 | return delete $AliasToID{$alias}; | ||||
145 | } | ||||
146 | |||||
147 | BEGIN | ||||
148 | # spent 50.6ms (36µs+50.6) within DateTime::Locale::BEGIN@148 which was called
# once (36µs+50.6ms) by DateTime::BEGIN@41 at line 151 | ||||
149 | 2 | 37µs | 2 | 37.2ms | __PACKAGE__->register( DateTime::Locale::Catalog->Locales() ); # spent 37.2ms making 1 call to DateTime::Locale::register
# spent 16µs making 1 call to DateTime::Locale::Catalog::Locales |
150 | __PACKAGE__->add_aliases( DateTime::Locale::Catalog->Aliases() ); # spent 13.2ms making 1 call to DateTime::Locale::add_aliases
# spent 158µs making 1 call to DateTime::Locale::Catalog::Aliases | ||||
151 | 1 | 703µs | 1 | 50.6ms | } # spent 50.6ms making 1 call to DateTime::Locale::BEGIN@148 |
152 | |||||
153 | sub ids { wantarray ? keys %DataForID : [ keys %DataForID ] } | ||||
154 | sub names { wantarray ? keys %NameToID : [ keys %NameToID ] } | ||||
155 | sub native_names { wantarray ? keys %NativeNameToID : [ keys %NativeNameToID ] } | ||||
156 | |||||
157 | # These are hardcoded for backwards comaptibility with the | ||||
158 | # DateTime::Language code. | ||||
159 | 1 | 10µs | my %OldAliases = | ||
160 | ( 'Afar' => 'aa', | ||||
161 | 'Amharic' => 'am_ET', | ||||
162 | 'Austrian' => 'de_AT', | ||||
163 | 'Brazilian' => 'pt_BR', | ||||
164 | 'Czech' => 'cs_CZ', | ||||
165 | 'Danish' => 'da_DK', | ||||
166 | 'Dutch' => 'nl_NL', | ||||
167 | 'English' => 'en_US', | ||||
168 | 'French' => 'fr_FR', | ||||
169 | # 'Gedeo' => undef, # XXX | ||||
170 | 'German' => 'de_DE', | ||||
171 | 'Italian' => 'it_IT', | ||||
172 | 'Norwegian' => 'no_NO', | ||||
173 | 'Oromo' => 'om_ET', # Maybe om_KE or plain om ? | ||||
174 | 'Portugese' => 'pt_PT', | ||||
175 | 'Sidama' => 'sid', | ||||
176 | 'Somali' => 'so_SO', | ||||
177 | 'Spanish' => 'es_ES', | ||||
178 | 'Swedish' => 'sv_SE', | ||||
179 | 'Tigre' => 'tig', | ||||
180 | 'TigrinyaEthiopian' => 'ti_ET', | ||||
181 | 'TigrinyaEritrean' => 'ti_ER', | ||||
182 | ); | ||||
183 | |||||
184 | sub load | ||||
185 | # spent 5.57ms (598µs+4.97) within DateTime::Locale::load which was called 40 times, avg 139µs/call:
# 17 times (281µs+568µs) by DateTime::Locale::Base::STORABLE_thaw at line 359 of DateTime/Locale/Base.pm, avg 50µs/call
# 17 times (211µs+445µs) by DateTime::new at line 204 of DateTime.pm, avg 39µs/call
# 5 times (85µs+225µs) by DateTime::Format::Strptime::new at line 143 of DateTime/Format/Strptime.pm, avg 62µs/call
# once (21µs+3.73ms) by DateTime::DefaultLocale at line 100 of DateTime.pm | ||||
186 | 206 | 1.08ms | my $class = shift; | ||
187 | 1 | 725µs | 40 | 1.16ms | my ($name) = validate_pos( @_, { type => SCALAR } ); # spent 1.16ms making 40 calls to Params::Validate::_validate_pos, avg 29µs/call |
188 | |||||
189 | # Support RFC 3066 language tags, which use '-' instead of '_'. | ||||
190 | $name =~ tr/-/_/; | ||||
191 | |||||
192 | my $key = $name; | ||||
193 | |||||
194 | return $LoadCache{$key} if exists $LoadCache{$key}; | ||||
195 | |||||
196 | # Custom class registered by user | ||||
197 | if ( $Class{$name} ) | ||||
198 | { | ||||
199 | return $LoadCache{$key} = $class->_load_class_from_id( $name, $Class{$name} ) | ||||
200 | } | ||||
201 | |||||
202 | # special case for backwards compatibility with DT::Language | ||||
203 | $name = $OldAliases{$name} if exists $OldAliases{$name}; | ||||
204 | |||||
205 | if ( exists $DataForID{$name} || exists $AliasToID{$name} ) # spent 3.81ms making 2 calls to DateTime::Locale::_load_class_from_id, avg 1.91ms/call | ||||
206 | { | ||||
207 | return $LoadCache{$key} = $class->_load_class_from_id($name); | ||||
208 | } | ||||
209 | |||||
210 | foreach my $h ( \%NameToID, \%NativeNameToID ) | ||||
211 | { | ||||
212 | return $LoadCache{$key} = $class->_load_class_from_id( $h->{$name} ) | ||||
213 | if exists $h->{$name}; | ||||
214 | } | ||||
215 | |||||
216 | if ( my $id = $class->_guess_id($name) ) | ||||
217 | { | ||||
218 | return $LoadCache{$key} = $class->_load_class_from_id($id); | ||||
219 | } | ||||
220 | |||||
221 | die "Invalid locale name or id: $name\n"; | ||||
222 | } | ||||
223 | |||||
224 | sub _guess_id | ||||
225 | { | ||||
226 | my $class = shift; | ||||
227 | my $name = shift; | ||||
228 | |||||
229 | # Strip off charset for LC_* ids : en_GB.UTF-8 etc | ||||
230 | $name =~ s/\..*$//; | ||||
231 | |||||
232 | my ($language, $script, $territory, $variant ) = | ||||
233 | _parse_id($name); | ||||
234 | |||||
235 | my @guesses; | ||||
236 | |||||
237 | if ( defined $script ) | ||||
238 | { | ||||
239 | my $guess = join '_', lc $language, ucfirst lc $script; | ||||
240 | |||||
241 | push @guesses, $guess; | ||||
242 | |||||
243 | $guess .= '_' . uc $territory if defined $territory; | ||||
244 | |||||
245 | # version with script comes first | ||||
246 | unshift @guesses, $guess; | ||||
247 | } | ||||
248 | |||||
249 | if ( defined $variant ) | ||||
250 | { | ||||
251 | push @guesses, | ||||
252 | join '_', lc $language, uc $territory, uc $variant; | ||||
253 | } | ||||
254 | |||||
255 | if ( defined $territory ) | ||||
256 | { | ||||
257 | push @guesses, | ||||
258 | join '_', lc $language, uc $territory; | ||||
259 | } | ||||
260 | |||||
261 | push @guesses, lc $language; | ||||
262 | |||||
263 | foreach my $id (@guesses) | ||||
264 | { | ||||
265 | return $id | ||||
266 | if exists $DataForID{$id} || exists $AliasToID{$id}; | ||||
267 | } | ||||
268 | } | ||||
269 | |||||
270 | sub _parse_id | ||||
271 | { | ||||
272 | $_[0] =~ /([a-z]+) # id | ||||
273 | (?: _([A-Z][a-z]+) )? # script - Title Case - optional | ||||
274 | (?: _([A-Z]+) )? # territory - ALL CAPS - optional | ||||
275 | (?: _([A-Z]+) )? # variant - ALL CAPS - optional | ||||
276 | /x; | ||||
277 | |||||
278 | return $1, $2, $3, $4; | ||||
279 | } | ||||
280 | |||||
281 | sub _load_class_from_id | ||||
282 | # spent 3.81ms (324µs+3.49) within DateTime::Locale::_load_class_from_id which was called 2 times, avg 1.91ms/call:
# 2 times (324µs+3.49ms) by DateTime::Locale::load at line 205, avg 1.91ms/call | ||||
283 | 30 | 114µs | my $class = shift; | ||
284 | my $id = shift; | ||||
285 | my $real_class = shift; | ||||
286 | |||||
287 | # We want the first alias for which there is data, even if it has | ||||
288 | # no corresponding .pm file. There may be multiple levels of | ||||
289 | # alias to go through. | ||||
290 | my $data_id = $id; | ||||
291 | while ( exists $AliasToID{$data_id} && ! exists $DataForID{$data_id} ) | ||||
292 | { | ||||
293 | $data_id = $AliasToID{$data_id}; | ||||
294 | } | ||||
295 | |||||
296 | $real_class ||= "DateTime::Locale::$data_id"; | ||||
297 | |||||
298 | unless ( $real_class->can('new') ) # spent 7µs making 2 calls to UNIVERSAL::can, avg 4µs/call | ||||
299 | { | ||||
300 | 1 | 89µs | eval "require $real_class"; | ||
301 | |||||
302 | die $@ if $@; | ||||
303 | } | ||||
304 | |||||
305 | my $locale = $real_class->new( %{ $DataForID{$data_id} }, # spent 66µs making 2 calls to DateTime::Locale::Base::new, avg 33µs/call | ||||
306 | id => $id, | ||||
307 | ); | ||||
308 | |||||
309 | return $locale if $DateTime::Locale::InGenerator; | ||||
310 | |||||
311 | if ( $locale->can('cldr_version') ) # spent 2µs making 2 calls to UNIVERSAL::can, avg 1µs/call | ||||
312 | { | ||||
313 | my $object_version = $locale->cldr_version(); # spent 4µs making 2 calls to DateTime::Locale::en_US::cldr_version, avg 2µs/call | ||||
314 | my $catalog_version = DateTime::Locale::Catalog->CLDRVersion(); # spent 5µs making 2 calls to DateTime::Locale::Catalog::CLDRVersion, avg 2µs/call | ||||
315 | |||||
316 | if ( $object_version ne $catalog_version ) | ||||
317 | { | ||||
318 | warn "Loaded $real_class, which is from an older version ($object_version)" | ||||
319 | . "of the CLDR database than this installation of" | ||||
320 | . "DateTime::Locale ($catalog_version).\n"; | ||||
321 | } | ||||
322 | } | ||||
323 | |||||
324 | return $locale; | ||||
325 | } | ||||
326 | |||||
327 | 1 | 16µs | 1; | ||
328 | |||||
329 | __END__ | ||||
330 | |||||
331 | =pod | ||||
332 | |||||
333 | =encoding utf8 | ||||
334 | |||||
335 | =head1 NAME | ||||
336 | |||||
337 | DateTime::Locale - Localization support for DateTime.pm | ||||
338 | |||||
339 | =head1 SYNOPSIS | ||||
340 | |||||
341 | use DateTime::Locale; | ||||
342 | |||||
343 | my $loc = DateTime::Locale->load('en_GB'); | ||||
344 | |||||
345 | print $loc->native_locale_name(), "\n", | ||||
346 | $loc->datetime_format_long(), "\n"; | ||||
347 | |||||
348 | # but mostly just things like ... | ||||
349 | |||||
350 | my $dt = DateTime->now( locale => 'fr' ); | ||||
351 | print "Aujourd'hui le mois est " . $dt->month_name(), "\n"; | ||||
352 | |||||
353 | =head1 DESCRIPTION | ||||
354 | |||||
355 | DateTime::Locale is primarily a factory for the various locale | ||||
356 | subclasses. It also provides some functions for getting information on | ||||
357 | all the available locales. | ||||
358 | |||||
359 | If you want to know what methods are available for locale objects, | ||||
360 | then please read the C<DateTime::Locale::Base> documentation. | ||||
361 | |||||
362 | =head1 USAGE | ||||
363 | |||||
364 | This module provides the following class methods: | ||||
365 | |||||
366 | =head2 DateTime::Locale->load( $locale_id | $locale_name | $alias ) | ||||
367 | |||||
368 | Returns the locale object for the specified locale id, name, or alias | ||||
369 | - see the C<DateTime::Locale::Catalog> documentation for a list of | ||||
370 | built in names and ids. The name provided may be either the English | ||||
371 | or native name. | ||||
372 | |||||
373 | If the requested locale is not found, a fallback search takes place to | ||||
374 | find a suitable replacement. | ||||
375 | |||||
376 | The fallback search order is: | ||||
377 | |||||
378 | language_script_territory | ||||
379 | language_script | ||||
380 | language_territory_variant | ||||
381 | language_territory | ||||
382 | language | ||||
383 | |||||
384 | Eg. For locale C<es_XX_UNKNOWN> the fallback search would be: | ||||
385 | |||||
386 | es_XX_UNKNOWN # Fails - no such locale | ||||
387 | es_XX # Fails - no such locale | ||||
388 | es # Found - the es locale is returned as the | ||||
389 | # closest match to the requested id | ||||
390 | |||||
391 | Eg. For locale C<es_Latn_XX> the fallback search would be: | ||||
392 | |||||
393 | es_Latn_XX # Fails - no such locale | ||||
394 | es_Latn # Fails - no such locale | ||||
395 | es_XX # Fails - no such locale | ||||
396 | es # Found - the es locale is returned as the | ||||
397 | # closest match to the requested id | ||||
398 | |||||
399 | If no suitable replacement is found, then an exception is thrown. | ||||
400 | |||||
401 | Please note that if you provide an B<id> to this method, then the | ||||
402 | returned locale object's C<id()> method will B<always> return the | ||||
403 | value you gave, even if that value was an alias to some other id. | ||||
404 | |||||
405 | This is done for forwards compatibility, in case something that is | ||||
406 | currently an alias becomes a unique locale in the future. | ||||
407 | |||||
408 | This means that the value of C<< $locale->id() >> and the object's | ||||
409 | class may not match. | ||||
410 | |||||
411 | The loaded locale is cached, so that B<locale objects may be | ||||
412 | singletons>. Calling C<< DateTime::Locale->register() >>, C<< | ||||
413 | DateTime::Locale->add_aliases() >>, or C<< | ||||
414 | DateTime::Locale->remove_alias() >> clears the cache. | ||||
415 | |||||
416 | =head2 DateTime::Locale->ids() | ||||
417 | |||||
418 | my @ids = DateTime::Locale->ids(); | ||||
419 | my $ids = DateTime::Locale->ids(); | ||||
420 | |||||
421 | Returns an unsorted list of the available locale ids, or an array | ||||
422 | reference if called in a scalar context. This list does not include | ||||
423 | aliases. | ||||
424 | |||||
425 | =head2 DateTime::Locale->names() | ||||
426 | |||||
427 | my @names = DateTime::Locale->names(); | ||||
428 | my $names = DateTime::Locale->names(); | ||||
429 | |||||
430 | Returns an unsorted list of the available locale names in English, or | ||||
431 | an array reference if called in a scalar context. | ||||
432 | |||||
433 | =head2 DateTime::Locale->native_names() | ||||
434 | |||||
435 | my @names = DateTime::Locale->native_names(); | ||||
436 | my $names = DateTime::Locale->native_names(); | ||||
437 | |||||
438 | Returns an unsorted list of the available locale names in their native | ||||
439 | language, or an array reference if called in a scalar context. All | ||||
440 | native names are utf8 encoded. | ||||
441 | |||||
442 | B<NB>: Many locales are only partially translated, so some native | ||||
443 | locale names may still contain some English. | ||||
444 | |||||
445 | =head2 DateTime::Locale->add_aliases ( $alias1 => $id1, $alias2 => $id2, ... ) | ||||
446 | |||||
447 | Adds an alias to an existing locale id. This allows a locale to be | ||||
448 | loaded by its alias rather than id or name. Multiple aliases are | ||||
449 | allowed. | ||||
450 | |||||
451 | If the passed locale id is neither registered nor listed in | ||||
452 | L<DateTime::Local::Catalog>'s list of ids, an exception is thrown. | ||||
453 | |||||
454 | DateTime::Locale->add_aliases( LastResort => 'es_ES' ); | ||||
455 | |||||
456 | # Equivalent to DateTime::Locale->load('es_ES'); | ||||
457 | DateTime::Locale->load('LastResort'); | ||||
458 | |||||
459 | You can also pass a hash reference to this method. | ||||
460 | |||||
461 | DateTime::Locale->add_aliases( { Default => 'en_GB', | ||||
462 | Alternative => 'en_US', | ||||
463 | LastResort => 'es_ES' } ); | ||||
464 | |||||
465 | =head2 DateTime::Locale->remove_alias( $alias ) | ||||
466 | |||||
467 | Removes a locale id alias, and returns true if the specified alias | ||||
468 | actually existed. | ||||
469 | |||||
470 | DateTime::Locale->add_aliases( LastResort => 'es_ES' ); | ||||
471 | |||||
472 | # Equivalent to DateTime::Locale->load('es_ES'); | ||||
473 | DateTime::Locale->load('LastResort'); | ||||
474 | |||||
475 | DateTime::Locale->remove_alias('LastResort'); | ||||
476 | |||||
477 | # Throws an exception, 'LastResort' no longer exists | ||||
478 | DateTime::Locale->load('LastResort'); | ||||
479 | |||||
480 | =head2 DateTime::Locale->register( { ... }, { ... } ) | ||||
481 | |||||
482 | This method allows you to register custom locales with the module. A | ||||
483 | single locale is specified as a hash, and you may register multiple | ||||
484 | locales at once by passing an array of hash references. | ||||
485 | |||||
486 | Until registered, custom locales cannot be instantiated via C<load()> | ||||
487 | and will not be returned by querying methods such as C<ids()> or | ||||
488 | C<names()>. | ||||
489 | |||||
490 | register( id => $locale_id, | ||||
491 | en_language => ..., # something like 'English' or 'Afar', | ||||
492 | |||||
493 | # All other keys are optional. These are: | ||||
494 | en_script => ..., | ||||
495 | en_territory => ..., | ||||
496 | en_variant => ..., | ||||
497 | |||||
498 | native_language => ..., | ||||
499 | native_sript => ..., | ||||
500 | native_territory => ..., | ||||
501 | native_variant => ..., | ||||
502 | |||||
503 | # Optional - defaults to DateTime::Locale::$locale_id | ||||
504 | class => $class_name, | ||||
505 | |||||
506 | replace => $boolean | ||||
507 | ) | ||||
508 | |||||
509 | The locale id and English name are required, and the following formats | ||||
510 | should used wherever possible: | ||||
511 | |||||
512 | id: languageId[_script][_territoryId[_variantId]] | ||||
513 | |||||
514 | Where: languageId = Lower case ISO 639 code - | ||||
515 | Always choose 639-1 over 639-2 where possible. | ||||
516 | |||||
517 | script = Title Case ISO 15924 script code | ||||
518 | |||||
519 | territoryId = Upper case ISO 3166 code - | ||||
520 | Always choose 3166-1 over 3166-2 where possible. | ||||
521 | |||||
522 | variantId = Upper case variant id - | ||||
523 | Basically anything you want, since this is typically the | ||||
524 | component that uniquely identifies a custom locale. | ||||
525 | |||||
526 | You cannot not use '@' or '=' in locale ids - these are reserved for | ||||
527 | future use. The underscore (_) is the component separator, and should | ||||
528 | not be used for any other purpose. | ||||
529 | |||||
530 | If the "native_*" components are supplied, they must be utf8 encoded. | ||||
531 | |||||
532 | If omitted, the native name is assumed to be identical to the English | ||||
533 | name. | ||||
534 | |||||
535 | If class is supplied, it must be the full module name of your custom | ||||
536 | locale. If omitted, the locale module is assumed to be a | ||||
537 | DateTime::Locale subclass. | ||||
538 | |||||
539 | Examples: | ||||
540 | |||||
541 | DateTime::Locale->register | ||||
542 | ( id => 'en_GB_RIDAS', | ||||
543 | en_language => 'English', | ||||
544 | en_territory => 'United Kingdom', | ||||
545 | en_variant => 'Ridas Custom Locale', | ||||
546 | ); | ||||
547 | |||||
548 | # Returns instance of class DateTime::Locale::en_GB_RIDAS | ||||
549 | my $l = DateTime::Locale->load('en_GB_RIDAS'); | ||||
550 | |||||
551 | DateTime::Locale->register | ||||
552 | ( id => 'hu_HU', | ||||
553 | en_language => 'Hungarian', | ||||
554 | en_territory => Hungary', | ||||
555 | native_language => 'Magyar', | ||||
556 | native_territory => 'Magyarország', | ||||
557 | ); | ||||
558 | |||||
559 | # Returns instance of class DateTime::Locale::hu_HU | ||||
560 | my $l = DateTime::Locale->load('hu_HU'); | ||||
561 | |||||
562 | DateTime::Locale->register | ||||
563 | ( id => 'en_GB_RIDAS', | ||||
564 | name => 'English United Kingdom Ridas custom locale', | ||||
565 | class => 'Ridas::Locales::CustomGB', | ||||
566 | ); | ||||
567 | |||||
568 | # Returns instance of class Ridas::Locales::CustomGB | ||||
569 | # NOT Ridas::Locales::Custom::en_GB_RIDAS ! | ||||
570 | my $l = DateTime::Locale->load('en_GB_RIDAS'); | ||||
571 | |||||
572 | If you register a locale for an id that is already registered, the | ||||
573 | "replace" parameter must be true or an exception will be thrown. | ||||
574 | |||||
575 | The complete name for a registered locale is generated by joining | ||||
576 | together the language, territory, and variant components with a single | ||||
577 | space. | ||||
578 | |||||
579 | This means that in the first example, the complete English and native | ||||
580 | names for the locale would be "English United Kingdom Ridas Custom | ||||
581 | Locale", and in the second example the complete English name is | ||||
582 | "Hungarian Hungary", while the complete native name is "Magyar | ||||
583 | Magyarország". The locale will be loadable by these complete names | ||||
584 | (English and native), via the C<load()> method. | ||||
585 | |||||
586 | =head1 ADDING CUSTOM LOCALES | ||||
587 | |||||
588 | These are added in one of two ways: | ||||
589 | |||||
590 | =over 4 | ||||
591 | |||||
592 | =item 1. | ||||
593 | |||||
594 | Subclass an existing locale implementing only the changes you require. | ||||
595 | |||||
596 | =item 2. | ||||
597 | |||||
598 | Create a completely new locale. | ||||
599 | |||||
600 | =back | ||||
601 | |||||
602 | In either case the locale MUST be registered before use. | ||||
603 | |||||
604 | =head2 Subclassing an existing locale | ||||
605 | |||||
606 | The following example sublasses the United Kingdom English locale to | ||||
607 | provide different date/time formats: | ||||
608 | |||||
609 | package Ridas::Locale::en_GB_RIDAS1; | ||||
610 | |||||
611 | use strict; | ||||
612 | use DateTime::Locale::en_GB; | ||||
613 | |||||
614 | use base 'DateTime::Locale::en_GB'; | ||||
615 | |||||
616 | my $locale_id = 'en_GB_RIDAS1'; | ||||
617 | |||||
618 | my $date_formats = | ||||
619 | { | ||||
620 | 'full' => '%A %{day} %B %{ce_year}', | ||||
621 | 'long' => '%{day} %B %{ce_year}', | ||||
622 | 'medium' => '%{day} %b %{ce_year}', | ||||
623 | 'short' => '%{day}/%m/%y', | ||||
624 | }; | ||||
625 | |||||
626 | my $time_formats = | ||||
627 | { | ||||
628 | 'full' => '%H h %{minute} %{time_zone_short_name}', | ||||
629 | 'long' => '%{hour12}:%M:%S %p', | ||||
630 | 'medium' => '%{hour12}:%M:%S %p', | ||||
631 | 'short' => '%{hour12}:%M %p', | ||||
632 | }; | ||||
633 | |||||
634 | sub date_format_full { $date_formats{full} } | ||||
635 | sub date_format_long { $date_formats{long} } | ||||
636 | sub date_format_medium { $date_formats{medium} } | ||||
637 | sub date_format_short { $date_formats{short} } | ||||
638 | |||||
639 | sub time_format_full { $time_formats{full} } | ||||
640 | sub time_format_long { $time_formats{long} } | ||||
641 | sub time_format_medium { $time_formats{medium} } | ||||
642 | sub time_format_short { $time_formats{short} } | ||||
643 | |||||
644 | 1; | ||||
645 | |||||
646 | Now register it: | ||||
647 | |||||
648 | DateTime::Locale->register | ||||
649 | ( id => 'en_GB_RIDAS1', | ||||
650 | |||||
651 | # name, territory, and variant as described in register() documentation | ||||
652 | |||||
653 | class => 'Ridas::Locale::en_GB_RIDAS1', | ||||
654 | ); | ||||
655 | |||||
656 | =head2 Creating a completely new locale | ||||
657 | |||||
658 | You are, of course, free to subclass C<DateTime::Locale::Base> if you | ||||
659 | want to, though this is not required. | ||||
660 | |||||
661 | Remember to register your custom locale! | ||||
662 | |||||
663 | Of course, you can always do the registration in the module itself, | ||||
664 | and simply load it before using it. | ||||
665 | |||||
666 | A completely new custom locale, one which does not subclass | ||||
667 | L<DateTime::Locale::Base>, must implement a number of methods. | ||||
668 | |||||
669 | The following methods can be used to get information about the | ||||
670 | locale's id and name. | ||||
671 | |||||
672 | =over 4 | ||||
673 | |||||
674 | =item * $locale->id() | ||||
675 | |||||
676 | The complete locale id, something like "en_US". | ||||
677 | |||||
678 | =item * $locale->language_id() | ||||
679 | |||||
680 | The language portion of the id, like "en". | ||||
681 | |||||
682 | =item * $locale->script_id() | ||||
683 | |||||
684 | The script portion of the id, like "Hant". | ||||
685 | |||||
686 | =item * $locale->territory_id() | ||||
687 | |||||
688 | The territory portion of the id, like "US". | ||||
689 | |||||
690 | =item * $locale->variant_id() | ||||
691 | |||||
692 | The variant portion of the id, like "PREEURO". | ||||
693 | |||||
694 | =item * $locale->name() | ||||
695 | |||||
696 | The locale's complete name, which always includes at least a language | ||||
697 | component, plus optional territory and variant components. Something | ||||
698 | like "English United States". The value returned will always be in | ||||
699 | English. | ||||
700 | |||||
701 | =item * $locale->language() | ||||
702 | |||||
703 | =item * $locale->script() | ||||
704 | |||||
705 | =item * $locale->territory() | ||||
706 | |||||
707 | =item * $locale->variant() | ||||
708 | |||||
709 | The relevant component from the locale's complete name, like "English" | ||||
710 | or "United States". | ||||
711 | |||||
712 | =item * $locale->native_name() | ||||
713 | |||||
714 | The locale's complete name in localized form as a UTF-8 string. | ||||
715 | |||||
716 | =item * $locale->native_language() | ||||
717 | |||||
718 | =item * $locale->native_script() | ||||
719 | |||||
720 | =item * $locale->native_territory() | ||||
721 | |||||
722 | =item * $locale->native_variant() | ||||
723 | |||||
724 | The relevant component from the locale's complete native name as a | ||||
725 | UTF-8 string. | ||||
726 | |||||
727 | =back | ||||
728 | |||||
729 | The following methods all return an array reference containing the | ||||
730 | specified data. | ||||
731 | |||||
732 | The format methods return strings that might be used a part of a | ||||
733 | string, like "the month of July", and should always return a set of | ||||
734 | unique values. The stand alone values are for use in things like | ||||
735 | calendars, and the narrow form may not be unique (for example, in day | ||||
736 | column heading for a calendar it's okay to have "T" for both Tuesday | ||||
737 | and Thursday). | ||||
738 | |||||
739 | =over 4 | ||||
740 | |||||
741 | =item * $locale->month_format_wide() | ||||
742 | |||||
743 | =item * $locale->month_format_abbreviated($dt) | ||||
744 | |||||
745 | =item * $locale->month_format_narrow($dt) | ||||
746 | |||||
747 | =item * $locale->month_stand_alone_wide() | ||||
748 | |||||
749 | =item * $locale->month_stand_alone_abbreviated($dt) | ||||
750 | |||||
751 | =item * $locale->month_stand_alone_narrow($dt) | ||||
752 | |||||
753 | =item * $locale->day_format_wide() | ||||
754 | |||||
755 | =item * $locale->day_format_abbreviated($dt) | ||||
756 | |||||
757 | =item * $locale->day_format_narrow($dt) | ||||
758 | |||||
759 | =item * $locale->day_stand_alone_wide() | ||||
760 | |||||
761 | =item * $locale->day_stand_alone_abbreviated($dt) | ||||
762 | |||||
763 | =item * $locale->day_stand_alone_narrow($dt) | ||||
764 | |||||
765 | =item * $locale->quarter_format_wide() | ||||
766 | |||||
767 | =item * $locale->quarter_format_abbreviated($dt) | ||||
768 | |||||
769 | =item * $locale->quarter_format_narrow($dt) | ||||
770 | |||||
771 | =item * $locale->quarter_stand_alone_wide() | ||||
772 | |||||
773 | =item * $locale->quarter_stand_alone_abbreviated($dt) | ||||
774 | |||||
775 | =item * $locale->quarter_stand_alone_narrow($dt) | ||||
776 | |||||
777 | =item * $locale->am_pm_abbreviated() | ||||
778 | |||||
779 | =item * $locale->era_wide() | ||||
780 | |||||
781 | =item * $locale->era_abbreviated($dt) | ||||
782 | |||||
783 | =item * $locale->era_narrow($dt) | ||||
784 | |||||
785 | =back | ||||
786 | |||||
787 | The following methods return strings appropriate for the | ||||
788 | C<< DateTime->format_cldr() >> method: | ||||
789 | |||||
790 | =over 4 | ||||
791 | |||||
792 | =item * $locale->date_format_full() | ||||
793 | |||||
794 | =item * $locale->date_format_long() | ||||
795 | |||||
796 | =item * $locale->date_format_medium() | ||||
797 | |||||
798 | =item * $locale->date_format_short() | ||||
799 | |||||
800 | =item * $locale->date_format_default() | ||||
801 | |||||
802 | =item * $locale->time_format_full() | ||||
803 | |||||
804 | =item * $locale->time_format_long() | ||||
805 | |||||
806 | =item * $locale->time_format_medium() | ||||
807 | |||||
808 | =item * $locale->time_format_short() | ||||
809 | |||||
810 | =item * $locale->time_format_default() | ||||
811 | |||||
812 | =item * $locale->datetime_format_full() | ||||
813 | |||||
814 | =item * $locale->datetime_format_long() | ||||
815 | |||||
816 | =item * $locale->datetime_format_medium() | ||||
817 | |||||
818 | =item * $locale->datetime_format_short() | ||||
819 | |||||
820 | =item * $locale->datetime_format_default() | ||||
821 | |||||
822 | =back | ||||
823 | |||||
824 | A locale may also offer one or more formats for displaying part of a | ||||
825 | datetime, such as the year and month, or hour and minute. | ||||
826 | |||||
827 | =over 4 | ||||
828 | |||||
829 | =item * $locale->format_for($name) | ||||
830 | |||||
831 | These are accessed by passing a name to C<< $locale->format_for(...) | ||||
832 | >>, where the name is a Java-style format specifier. | ||||
833 | |||||
834 | The return value is a string suitable for passing to C<< | ||||
835 | $dt->format_cldr() >>, so you can do something like this: | ||||
836 | |||||
837 | print $dt->format_cldr( $dt->locale()->format_for('MMMdd') ) | ||||
838 | |||||
839 | which for the "en" locale would print out something like "08 Jul". | ||||
840 | |||||
841 | Note that the localization may also include additional text specific to the | ||||
842 | locale. For example, the "MMMMd" format for the "zh" locale includes the | ||||
843 | Chinese characters for "day" (日) and month (月), so you get something like "8 | ||||
844 | 月23日". | ||||
845 | |||||
846 | =item * $locale->_available_format() | ||||
847 | |||||
848 | This should return a list of all the format names that could be passed | ||||
849 | to C<< $locale->format_for() >>. | ||||
850 | |||||
851 | =back | ||||
852 | |||||
853 | The following methods deal with the default format lengths: | ||||
854 | |||||
855 | =over 4 | ||||
856 | |||||
857 | =item * $locale->default_date_format_length() | ||||
858 | |||||
859 | =item * $locale->default_time_format_length() | ||||
860 | |||||
861 | These methods return one of "full", "long", "medium", or "short", | ||||
862 | indicating the current default format length. | ||||
863 | |||||
864 | The default when an object is created is determined by the CLDR locale | ||||
865 | data. | ||||
866 | |||||
867 | =item * $locale->set_default_date_format_length($length) | ||||
868 | |||||
869 | =item * $locale->set_default_time_format_length($length) | ||||
870 | |||||
871 | These methods accept one of "full", "long", "medium", or "short", | ||||
872 | indicating the new default format length. | ||||
873 | |||||
874 | =back | ||||
875 | |||||
876 | =head1 SUPPORT | ||||
877 | |||||
878 | Please be aware that all locale data has been generated from the CLDR | ||||
879 | (Common Locale Data Repository) project locales data). The data B<is> | ||||
880 | currently incomplete, and B<will> contain errors in some locales. | ||||
881 | |||||
882 | When reporting errors in data, please check the primary data sources | ||||
883 | first, then where necessary report errors directly to the primary | ||||
884 | source via the CLDR bug report system. See | ||||
885 | http://unicode.org/cldr/filing_bug_reports.html for details. | ||||
886 | |||||
887 | Once these errors have been confirmed, please forward the error report | ||||
888 | and corrections to the DateTime mailing list, datetime@perl.org. | ||||
889 | |||||
890 | Support for this module is provided via the datetime@perl.org email | ||||
891 | list. See http://lists.perl.org/ for more details. | ||||
892 | |||||
893 | =head1 DONATIONS | ||||
894 | |||||
895 | If you'd like to thank me for the work I've done on this module, | ||||
896 | please consider making a "donation" to me via PayPal. I spend a lot of | ||||
897 | free time creating free software, and would appreciate any support | ||||
898 | you'd care to offer. | ||||
899 | |||||
900 | Please note that B<I am not suggesting that you must do this> in order | ||||
901 | for me to continue working on this particular software. I will | ||||
902 | continue to do so, inasmuch as I have in the past, for as long as it | ||||
903 | interests me. | ||||
904 | |||||
905 | Similarly, a donation made in this way will probably not make me work | ||||
906 | on this software much more, unless I get so many donations that I can | ||||
907 | consider working on free software full time, which seems unlikely at | ||||
908 | best. | ||||
909 | |||||
910 | To donate, log into PayPal and send money to autarch@urth.org or use | ||||
911 | the button on this page: | ||||
912 | L<http://www.urth.org/~autarch/fs-donation.html> | ||||
913 | |||||
914 | =head1 AUTHORS | ||||
915 | |||||
916 | Richard Evans <rich@ridas.com> | ||||
917 | |||||
918 | Dave Rolsky <autarch@urth.org> | ||||
919 | |||||
920 | These modules are loosely based on the DateTime::Language modules, | ||||
921 | which were in turn based on the Date::Language modules from Graham | ||||
922 | Barr's TimeDate distribution. | ||||
923 | |||||
924 | =head1 COPYRIGHT | ||||
925 | |||||
926 | Copyright (c) 2003 Richard Evans. Copyright (c) 2004-2008 David | ||||
927 | Rolsky. All rights reserved. This program is free software; you can | ||||
928 | redistribute it and/or modify it under the same terms as Perl itself. | ||||
929 | |||||
930 | This program is free software; you can redistribute it and/or modify | ||||
931 | it under the same terms as Perl itself. | ||||
932 | |||||
933 | The full text of the license can be found in the F<LICENSE> file included | ||||
934 | with this module. | ||||
935 | |||||
936 | The locale modules in directory C<DateTime/Locale/> have been | ||||
937 | generated from data provided by the CLDR project, see | ||||
938 | C<DateTime/Locale/LICENSE.cldr> for details on the CLDR data's | ||||
939 | license. | ||||
940 | |||||
941 | =head1 SEE ALSO | ||||
942 | |||||
943 | L<DateTime::Locale::Base> | ||||
944 | |||||
945 | datetime@perl.org mailing list | ||||
946 | |||||
947 | http://datetime.perl.org/ | ||||
948 | |||||
949 | =cut | ||||
950 | |||||
# spent 294µs within DateTime::Locale::CORE:match which was called 466 times, avg 630ns/call:
# 466 times (294µs+0s) by DateTime::Locale::_register at line 65 of DateTime/Locale.pm, avg 630ns/call |