Poniższy artykuł pochodzi z serii Przygotowań do egzaminu 70-536.
Globalizacja to proces tworzenia aplikacji która wspomaga nasz “lokalny” interfejs. Przez lokalny należy rozumieć kulturę wyświetlania liczb, dat czy innych informacji. .NET Framework jest w stanie zrobić większość rzeczy za użytkownika, my jednak musimy zrozumieć jak korzystać z przewidzianych narzędzi. Na przykład w Stanach Zjednoczonych separatorem “miejsc po przecinku” (mówiąc po polsku ;) )jest kropka.
Ustawienia kultury
Możemy użyć dwóch właściwości do ustawienia kultury z jakiej chcemy skorzystać w naszym programie.
Thread.CurrentThread.CurrentCulture – nie można tutaj ustawić neutralnej kultury, określić samego języka w obiekcie CurrentCulture typu fr, en tylko trzeba wybrać ze zdefiniowanych kultur zarówno język jak i regionalne formatowanie typu fr-FR.
oraz
Thread.CurrentThread.CurrentUICulture - Określa, jakie zasoby są ładowane przez Resource Manager, jeśli przewidziane są środki w wielu językach. Ponieważ ten kontroluje tylko w jakim języku są używane, można zdefiniować CurrentUICulture z obu kultur neutralnie lub wyszczególnione.
Rozważmy następujący kod:
1: //C#
2: // Change the current culture
3: Thread.CurrentThread.CurrentCulture = new CultureInfo("es-ES");
4: Thread.CurrentThread.CurrentUICulture = new CultureInfo("es-ES");
5: MessageBox.Show(Thread.CurrentThread.CurrentCulture.ToString());
6: double d = 1234567.89;
7: // Show the figure as currency using the current culture
8: MessageBox.Show(d.ToString("C"));
9: // Show the current time using the current culture
10: MessageBox.Show(DateTime.Now.ToString());
Ten kod przykładowy tworzy następujące dane wyjściowe dla kultury es-ES:
es-ES
1.234.567,89 €
17/08/2008 11:07:46
W poprzednim przykładzie na sztywno wpisaliśmy kulturę do naszego kodu. Jeśli jednak mamy przetłumaczoną aplikacje na język niemiecki, hiszpański i angielski to musimy użytkownikowi dać do wyboru tylko jeden z trzech języków. Można także pobrać tablicę wszystkich dostępnych kultur, wywołując metodę System.Globalization.CultureInfo.GetCultures. Oraz z typu wyliczeniowego CultureTypes wybrać interesujące nas kultury. Najbardziej przydatne wartości z CultureTypes:
AllCultures- wszystkie kultury które przewidziano w .NET Framework
NeutralCultures- neutralna kultura która zapewnia tylko język a nie formatowanie danych.
SpecificCultures- wyszczególniona kultura, język + formatowanie danych
Jak formatować dane wyjściowe z różnych kultur
Poniższy kod demonstruje wyświetlanie instancji DateTime w różnych kulturach.
1: // C#
2: // Display the current time using the default culture
3: Console.WriteLine(DateTime.Now.ToString());
4: // Display the current time using the English-Great Britain culture
5: Console.WriteLine(DateTime.Now.ToString(new CultureInfo("en-GB")));
6: // Display the current time using the Russian culture
7: Console.WriteLine(DateTime.Now.ToString(new CultureInfo("ru-RU")));
Zakładając, że komputer domyślnie jest ustawiony na en-US, poprzedni kod daje następujący wynik:
8/17/2008 10:06:31 PM
17/08/2008 20:06:31
17.08.2008 20:06:31
Zwróćmy uwagę na następujące rzeczy:
W kulturze en-US data wyświetlana jest w formacie mm/dd/yyyy i czas AM/PM
W kulturze en-GB data wyświetlana jest w formacie dd/mm/yyyy
W kulturze ru-RU data wyświetlana jest w formacie dd.mm.yyyy
Rozważmy teraz wyświetlanie walut dla tych samych kultur:
1: // C#
2: double d = 1234567.89;
3: // Show the figure as currency using the default culture
4: Console.WriteLine(d.ToString("C"));
5: // Show the figure as currency using the English-Great Britain culture
6: Console.WriteLine(d.ToString("C", new CultureInfo("en-GB")));
7: // Show the figure as currency using the Russian culture
8: Console.WriteLine(d.ToString("C", new CultureInfo("ru-RU")));
Analogicznie do poprzedniego przykładu i poprzednich kultur uzyskamy:
$1,234,567.89
£1,234,567.89
1 234 567,89p.
Ja sformatować dane ręcznie?
Jeśli chcemy edytować dane ręcznie musimy uzyskać informacje o danej kulturze, sposobie formatowania przy użyciu np. CultureInfo.NumberFormat lub CultureInfo.DateTimeFormat. Poniższy kod pokazuje jak używać NumberFormat.Number-DecimalSeparator, NumberFormat.NumberGroupSizes, i NumberFormat.NumberGroupSeparator do wyświetlania długich liczb.
1: // C#
2: public static void Main()
3: {
4: FormatData(new CultureInfo("es-ES"));
5: FormatData(new CultureInfo("ru-RU"));
6: FormatData(new CultureInfo("en-US"));
7: Console.ReadKey();
8: }
9: private static void FormatData(CultureInfo ci)
10: {
11: // Display the selected culture
12: Console.WriteLine(ci.ToString() + ":");
13: // Identify the number and copy it to a string
14: double d = 1234567.89;
15: string formattedNumber = d.ToString();
16: // Identify the location of the culture-sensitive decimal point in the number
17: int decimalIndex = formattedNumber.IndexOf(
18: Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator) + 1;
19: // Extract only the decimal portion of the number
20: formattedNumber = formattedNumber.Substring(
21: decimalIndex, formattedNumber.Length - decimalIndex);
22: // Add the culture-specific decimal point before the number
23: formattedNumber = ci.NumberFormat.NumberDecimalSeparator + formattedNumber;
24: // Extract only the whole portion of the number
25: string wholeDigits = Math.Floor(d).ToString();
26: // Add each whole digit to formattedNumber, with grouping separators
27: for (int a = 0; a < wholeDigits.Length; a++)
28: {
29: // Examine CultureInfo.NumberFormat.NumberGroupSizes to determine
30: // whether the current location requires a separator
31: bool requiresSeparator = false;
32: foreach (int sep in ci.NumberFormat.NumberGroupSizes)
33: {
34: if ( (a > 0) && ((a % sep) == 0) )
35: {
36: requiresSeparator = true;
37: }
38: }
39: // Add a separator if required
40: if (requiresSeparator)
41: {
42: formattedNumber = ci.NumberFormat.NumberGroupSeparator + formattedNumber;
43: }
44: // Add the number to the final string
45: formattedNumber =
46: wholeDigits.ToCharArray()[wholeDigits.Length - a - 1] + formattedNumber;
47: }
48: // Display the manual results and the automatically formatted version
49: Console.WriteLine(" Manual: {0}", formattedNumber);
50: Console.WriteLine(" Automatic: {0}", d.ToString("N", ci));
51: }
Dane wyjściowe:
es-ES:
Manual: 1.234.567,89
Automatic: 1.234.567,89
ru-RU:
Manual: 1 234 567,89
Automatic: 1 234 567,89
en-US:
Manual: 1,234,567.89
Automatic: 1,234,567.89
Sortowanie i porównywanie obiektów
Mamy świadomość, że w zależności od kultury inaczej sortuje się alfabet (bo np. mogą występować różne specyficzne znaki) czy też będzie brana pod uwagę wielkość liter. Poniższy przykład pokazuje to na przykładzie znaku Æ dla dwóch kultur:
1: // C#
2: public static void Main()
3: {
4: string[] words = new string[] { "Apple", "Æble" };
5: Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
6: SortWords(words);
7: Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");
8: SortWords(words);
9: }
10: private static void SortWords(string[] words)
11: {
12: Console.WriteLine(Thread.CurrentThread.CurrentCulture);
13: Array.Sort(words);
14: foreach (string s in words)
15: {
16: Console.WriteLine(s);
17: }
18: }
Na ekranie konsoli w wyniku dostaniemy:
en-US
Æble
Apple
da-DK
Apple
Æble
W traning kit jest ładna tabelka która pokazuje kultury obsługujące różne sortowania etc.
To tyle w tym temacie. Więcej informacji można znaleźć w traning kit a dokładnie mówiąc m.in opis wielu właściwości dla kultur…jest tego chyba z 3 strony oraz krótki opis jak stworzyć własną kulturę. Tym artykułem również kończymy na naszej stornie cykl artykułów przygotowujących do egzaminu 70-536. Artykuły te należy traktować jako ostatnie przypomnienie najważniejszych informacji przed samym egzaminem. Dzięki wszystkim którzy czytali artykuły, dzielili się swoimi uwagami i spostrzeżeniami.
Poniższy artykuł pochodzi z serii Przygotowań do egzaminu 70-536.