.NET - Globalizace a lokalizace aplikací (1.)
V následujících dvou článcích se podíváme na prostředky, které .NET poskytuje pro tvorbu globalizovatelných a lokalizovatelných aplikací. Globalizace - která je tématem této části - znamená, že vaše aplikace funguje korektně v libovolném prostředí (tedy i pod operačním systémem s jiným jazykem a lokálním nastavením) a také se podle tohoto nastavení chová.
Lokalizovatelnost aplikací (o které bude řeč v příštím článku) znamená, že aplikace má oddělené zdroje, které jsou závislé na jazyce od samotného kódu. Takovouto lokalizovatelnou aplikaci lze snadno lokalizovat, tedy doplnit o zdroje v dalším jazyce.
Více o těchto pojmech naleznete například v MSDN v sekci Planning World-Ready Applications [1].
Co se dočtete v této části tutoriálu
- Základní přehled objektů jmenného prostoru
System.Globalization
- Jak lze zjišťovat a nastavovat aktuální jazykové nastavení aplikace
- Jak formátovat data do podoby odpovídající aktuálnímu nastavení
- Jak ukládat data ve formátu nezávislém na nastavení
Objekty pro globalizaci
Pro používání objektů umožňujících tvorbu globalizovatelných aplikací
budete potřebovat zejména jmenný prostor System.Globalization
.
Základním objektem umožňující zjišťování systémového nastavení je
objekt CultureInfo
. Tento objekt obsahuje všechno základní
nastavení a obsahuje vlastnosti které vrací objekty s informacemi
o dalších detailech nastavení, jako je například kalendář (vlastnost Calendar
).
Instanci tohoto objektu s aktuálním nastavením lze získat pomocí
staticke vlastnosti CultureInfo.CurrentCulture
.
Je také možno získat výchozí nastavení pro daný jazyk a zemi a to pomocí
standardních kódů popisovaných v RFC specifikaci [2].
Ve zkratce tyto kódy vypadají takto xx-YY
, kde xx
určuje jazyk a YY
určuje nastavení specifické země.
Například kód pro češtinu je cs
a pro české nastavení cs-CZ
,
angličtina používaná v USA má kód en-US
a britské
nastavení má en-GB
. Kompletní seznam všech podporovaných nastavení
naleznete v MSDN dokumentaci u popisu třídy CultureInfo [3].
Lokální nastavení
V následující ukázce se podíváme jak zle zjistit aktuální nastavení a jak lze získat všechna možná nastavení .NET Frameworku:
// budeme pracovat s objekty Thread a CultureInfo using System.Globalization; using System.Threading; ... // zjisti vsechny mozna nastaveni CultureInfo[] cultures= CultureInfo.GetCultures(CultureTypes.AllCultures); // Vypise jmena vsech nastaveni foreach(CultureInfo culture in cultures) { Console.WriteLine(culture.DisplayName); } // Vypise aktualni nastaveni CultureInfo current=Thread.CurrentThread.CurrentCulture; Console.WriteLine(current.DisplayName);
Nastavení CurrentCulture
je specifické pro každé vlákno, proto
se pro zjišťování nastavení používá vlastnost Thread.CurrentThread
,
která vrací objekt aktuálního vlákna. Měnit nastavení lze opět pouze pro aktuální
vlákno a to nastavením vlastnosti CurrentCulture
. Při změně nastavení
je ale potřeba používat pouze specifické nastavení (tedy například nelze použít
informace s kódem cs
, ale je potřeba i určení země, tedy
cs-CZ
). K tomuto účelu slouží metoda CreateSpecificCulture
jak je vidět v následující ukázce:
// Vytvori specificke CultureInfo pro anglictinu CultureInfo eng=CultureInfo.CreateSpecificCulture("en"); // Vypsat informace o CultureInfo Console.WriteLine("{0} - {1}",eng.Name,eng.DisplayName); // Nastavit aktualni culture na en-US Thread.CurrentThread.CurrentCulture=eng;
Výstup programu bude: en-US - English (United States)
Možné chyby
Při nastavování CurrentCulture
dojde k výjimce pokud se pokusíte
nastavit CultureInfo, které nepopisuje specifické nastavení. Také může dojít
k chybě při nastavení jednoho z několka kódů, které jsou sice podporovány v
.NET Frameworku, ale ne ve WinAPI a vzhledem k tomu, že toto volání vnitřně
s WinAPI pracuje dojde k chybě (jedná se například o zh-CHT
-
Traditional Chinese).
Formátování dat
Pokud používáte metody ToString
nebo například Double.Parse
k převodu čísel a řetězců, automaticky se vždy použije aktuální nastavení.
Pokud tedy na systému s českým nastavením převedete číslo s desetinnou částí na
textový řetězec, dostanete desetinnou čárku a v anglickém nastavení dostanete
desetinnou tečku. Při volání metody Parse
se opět předpokládá,
že předávaný řetězec bude v aktuálním nastavení. Toto nastavení lze obejít tak,
že metodě jako druhý parametr předáte objekt CultureInfo
, kterým
se má metoda řídit. Tato pravidla platí také pro strukturu DateTime
,
pomocí které lze pracovat s časem.
// Vypise cislo PI ve francouzskem formatu CultureInfo frCulture=CultureInfo.CreateSpecificCulture("fr"); string pi=Math.PI.ToString(frCulture); Console.WriteLine(pi); // .. a prevod retezce zpet na cislo double dblPi=Double.Parse(pi,frCulture);
Další co .NET Framework umožňuje, je získání jmen měsíců nebo dnů v týdnu,
takže pokud ve vaší aplikaci chcete zobrazovat například ovládací prvek
DropDownList
se seznamem měsíců, není potřeba tyto měsíce
psát do kódu, ale lze je získat za běhu a to přímo v jazyce, který má
uživatel nastavený v operačním systému.
// Naplni seznam monthList jmeny mesicu
DateTimeFormatInfo df=CurrentCulture.DateTimeFormat;
for(int i=0; i<12; i++)
{
monthList.Items.Add(df.MonthNames[i]);
}
Neutrální formát
Pokud chcete ve vaší aplikaci ukládat data například do souboru tak, aby
nebyla závislá na aktuálním nastavení můžete použít takzvanou invariant culture,
která za všech podmínek popisuje stejné nastavení. K získání tohoto nastavení
lze použít statickou vlastnost objektu CultureInfo
a to
InvariantCulture
. V následující ukázce se podíváme, jak lze
zapsat a následně načíst ze souboru náhodné číslo ve formátu nezávislém
na nastavení (v tomto nastavní se desetinná čísla ukládají s tečkou).
using System.IO; using System.Globalization; ... // Ziska objekt popisujici nezavisle nastaveni CultureInfo invariant=CultureInfo.InvariantCulture; using(StreamWriter sw=new StreamWriter("C:\\test.txt")) { // Prevede nahodne cislo na retezec v invariant formatu // a ulozi jej do souboru.. Random rnd=new Random(); string num=rnd.NextDouble().ToString(invariant); sw.WriteLine(num); }
Načítání ze souboru vypadá velmi podobně:
using System.IO; using System.Globalization; ... // Ziska objekt popisujici nezavisle nastaveni CultureInfo invariant=CultureInfo.InvariantCulture; double num=0; using(StreamReader sr=new StreamReader("C:\\test.txt")) { // Prevede nacteny retezec na cislo string str=sr.ReadLine(); num=Double.Parse(str,invariant); } // .. a vypise cislo ve formatu dle aktualniho nastaveni Console.WriteLine(num.ToString());
Soubory na stažení a odkazy
- [1] Overview of Globalization and Localization [^] - MSDN
- [2] RFC 1766 - Kódy pro identifikaci lokálního nastavení [^]
- [3] CultureInfo Class [^] - MSDN