in reply to Relationship between timezone country and locale territory?
Hi Nocturnus,
Not an expert on locales, but I think the modules Locale::Codes::Language and Locale::Codes::Country might be helpful. I played with this a bit and here's my naive implementation which seems to work on my Linux box. See also Finding locales in perllocale.
use Locale::Codes::Language 'code2language'; use Locale::Codes::Country 'code2country'; for (`locale -a`) { chomp; my ($lang,$terr) = /^(\w+)_(\w+)\b/; print "$_ - ",code2language($lang)//'(unknown)', " - ",code2country($terr)//'(unknown)',"\n"; }
Update: You said "I don't think that (all) territory codes are valid country codes or vice versa". The information I am finding is that locale names are typically (apparently this varies from system to system) made up of the ISO 639 (language) and ISO 3166-1 (country) codes, which is what the two aforementioned modules handle. Also, at least on Debian-based systems, the list of all supported locales (as opposed to just the ones installed reported by locale -a) is in the file /usr/share/i18n/SUPPORTED.
Update 2: I assume the list of supported locales is not an exhaustive list of which languages are spoken in each country. You'll have to draw the line somewhere though, depending on what you want the user's choice to mean in your application (do you plan on supporting hundreds of locales?). Anyway, I revised the script based on the above:
#!/usr/bin/env perl use warnings; use strict; use Locale::Codes::Language 'code2language'; use Locale::Codes::Country 'code2country'; # list of supported locales (at least on Debian-based systems) open my $fh, '<', '/usr/share/i18n/SUPPORTED' or die $!; chomp( my @locales = grep {/\S/ && !/^\s*#/} <$fh> ); close $fh; # just a test of getting installed locales chomp( my @installed_locales = `locale -a` ); push @locales, @installed_locales; my %locales; for (@locales) { my ($lang,$terr) = /^([a-z]+)(?:_([a-z]+))?\b/i; $terr = code2country($terr) ||"unknown"; $lang = code2language($lang)||"unknown"; push @{ $locales{$terr}{$lang} }, $_; } for my $terr (sort keys %locales) { print "$terr\n"; for my $lang (sort keys %{ $locales{$terr} }) { print "\t$lang: ", join(" / ",@{ $locales{$terr}{$lang} }), "\n"; } }
Update 3: Ok, last update for tonight ;-) You asked how to match the locale codes to timezone names, and the documentation for DateTime::TimeZone->names_in_country says that it accepts two-letter ISO3166 codes, which is apparently the same code typically used in locale names, so you should be able to just match those up.
Hope this helps,
-- Hauke D
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Relationship between timezone country and locale territory? (updated x3)
by Nocturnus (Scribe) on Sep 15, 2016 at 06:26 UTC |