Internacionalizácia a lokalizácia v prostredí Java 8

1. Prehľad

Internacionalizácia je proces prípravy aplikácie na podporu rôznych jazykových, regionálnych, kultúrnych alebo politicky špecifických údajov. Je to podstatný aspekt každej modernej viacjazyčnej aplikácie.

Na ďalšie čítanie, mali by sme vedieť, že pre internacionalizáciu existuje veľmi populárna skratka (pravdepodobne populárnejšia ako samotný názov) - i18n kvôli 18 písmenám medzi „i“ a „n“.

Pre súčasné podnikové programy je zásadné slúžiť ľuďom z rôznych častí sveta alebo z rôznych kultúrnych oblastí. Rozdielne kultúrne alebo jazykové regióny neurčujú iba opisy špecifické pre daný jazyk, ale aj menu, zastúpenie čísel a dokonca odlišné zloženie dátumu a času.

Zamerajme sa napríklad na čísla špecifické pre jednotlivé krajiny. Majú rôzne desatinné miesta a tisíc oddeľovačov:

  • 102 300,45 (Spojené štáty)
  • 102 300,45 (Poľsko)
  • 102 300,45 (Nemecko)

Existujú aj rôzne formáty dátumu:

  • Pondelok 1. januára 2018 15:20:34 SEČ (USA)
  • lundi 1 janvier 2018 15 h 20 SEČ (Francúzsko).
  • 2018 年 1 月 1 日 星期一 下午 03 时 20 分 34 秒 SEČ (Čína)

Navyše majú rôzne krajiny jedinečné symboly mien:

  • 1 200,60 GBP (Spojené kráľovstvo)
  • 1 200,60 € (Taliansko)
  • 1 200,60 € (Francúzsko)
  • 1 200,60 USD (Spojené štáty)

Dôležitým faktom je, že aj keď majú krajiny rovnakú menu a symbol meny - napríklad Francúzsko a Taliansko - pozícia ich meny môže byť odlišná.

2. Lokalizácia

V rámci Javy máme k dispozícii fantastickú funkciu zvanú Miestne nastavenie trieda.

Umožňuje nám rýchlo rozlišovať medzi kultúrnymi lokalitami a vhodne formátovať náš obsah. Je to nevyhnutné pre proces internacionalizácie. Rovnako ako i18n, aj lokalizácia má svoju skratku - l10n.

Hlavný dôvod použitia Miestne nastavenie je, že ku všetkým požadovaným formátom špecifickým pre miestne nastavenie je možné pristupovať bez opätovnej kompilácie. Aplikácia dokáže spracovať viac miestnych nastavení súčasne, takže podpora nového jazyka je jednoduchá.

Miestne nastavenia sú zvyčajne reprezentované jazykom, krajinou a skratkou variantu oddelené podčiarkovníkom:

  • de (nemčina)
  • it_CH (taliančina, Švajčiarsko)
  • sk_US_UNIX (Spojené štáty, platforma UNIX)

2.1. Polia

To sme sa už naučili Miestne nastavenie pozostáva z kódu jazyka, kódu krajiny a variantu. Nastaviť môžete ďalšie dve polia: skript a prípony.

Pozrime sa na zoznam polí a pozrime sa, aké sú pravidlá:

  • Jazyk môže byť ISO 639 alfa-2 alebo alfa-3 kód alebo čiastková značka registrovaného jazyka.
  • Región (Krajina) je ISO 3166 alfa-2 kód krajiny alebo OSN číselne-3 kód oblasti.
  • Varianta je veľkosť písmen alebo množina hodnôt špecifikujúcich variáciu a Miestne nastavenie.
  • Scenár musí byť platný ISO 15924 alfa-4 kód.
  • Prípony je mapa, ktorá sa skladá z jednomiestnych klávesov a String hodnoty.

Register čiastkových značiek jazyka IANA obsahuje možné hodnoty pre Jazyk, regiónu, varianta a scenár.

Nie je k dispozícii žiadny zoznam možných predĺženie hodnoty, ale hodnoty musia byť dobre formované BCP-47 podznačky. Kľúče a hodnoty sa vždy prevedú na malé písmená.

2.2. Locale. Staviteľ

Existuje niekoľko spôsobov tvorby Miestne nastavenie predmety. Jeden možný spôsob využíva Locale. Staviteľ. Locale. Staviteľ má päť nastavovacích metód, ktoré môžeme použiť na zostavenie objektu a zároveň na overenie týchto hodnôt:

Locale locale = new Locale.Builder () .setLanguage ("fr") .setRegion ("CA") .setVariant ("POSIX") .setScript ("Latn") .build ();

The String reprezentácia vyššie uvedeného Miestne nastavenie je fr_CA_POSIX_ # latn.

Je dobré to vedieť nastavenie „variantu“ môže byť trochu zložité, pretože na hodnoty variantov neexistuje oficiálne obmedzenie, hoci metóda setter vyžaduje, aby bola BCP-47 vyhovujúci.

Inak to bude vrhať IllformedLocaleException.

V prípade, že potrebujeme použiť hodnotu, ktorá neprejde validáciou, môžeme použiť Miestne nastavenie konštruktory, pretože neoverujú hodnoty.

2.3. Konštruktéri

Miestne nastavenie má troch konštruktérov:

  • nové miestne nastavenie (reťazcový jazyk)
  • nové miestne nastavenie (jazyk reťazca, krajina reťazca)
  • nové miestne nastavenie (jazyk reťazca, krajina reťazca, variant reťazca)

Konštruktor s 3 parametrami:

Locale locale = new Locale ("pl", "PL", "UNIX");

Platný varianta musí byť a String 5 až 8 alfanumerických znakov alebo jednoduchá numerická, po ktorej nasledujú 3 alfanumerické znaky. „UNIX“ môžeme použiť iba na varianta pole iba prostredníctvom konštruktora, pretože nespĺňa tieto požiadavky.

Existuje však jedna nevýhoda použitia konštruktorov na vytváranie Miestne nastavenie objekty - nemôžeme nastavovať prípony a polia skriptu.

2.4. Konštanty

Toto je pravdepodobne najjednoduchší a najobmedzenejší spôsob získania Miestne nastavenia. The Miestne nastavenie trieda má niekoľko statických konštánt, ktoré predstavujú najobľúbenejšiu krajinu alebo jazyk:

Miestne nastavenie japonska = miestne nastavenie.JAPONSKO; Miestne japonské = miestne; JAPONSKÉ;

2.5. Jazykové značky

Iný spôsob tvorby Miestne nastavenie volá statickú továrenskú metódu forLanguageTag (reťazec languageTag). Táto metóda vyžaduje a String ktorý spĺňa IETF BCP 47 štandard.

Takto môžeme vytvoriť Veľkú Britániu Miestne nastavenie:

Locale uk = Locale.forLanguageTag ("en-UK");

2.6. Dostupné miestne nastavenia

Aj keď môžeme vytvoriť viac kombinácií Miestne nastavenie predmety, nemusíme byť schopní ich použiť.

Je potrebné si uvedomiť, že: Miestne nastavenia na platforme závisia od tých, ktoré boli nainštalované v rámci Java Runtime.

Ako používame Miestne nastavenia na formátovanie môžu mať rôzne formátory ešte menšiu množinu súborov Miestne nastavenia dostupné, ktoré sú nainštalované za behu programu.

Poďme skontrolovať, ako načítať polia dostupných miestnych nastavení:

Locale [] numberFormatLocales = NumberFormat.getAvailableLocales (); Locale [] dateFormatLocales = DateFormat.getAvailableLocales (); Locale [] locales = Locale.getAvailableLocales ();

Potom môžeme skontrolovať, či je naše Miestne nastavenie býva medzi dostupnými Miestne nastavenia.

Mali by sme si to pamätať sada dostupných miestnych nastavení sa líši pre rôzne implementácie platformy Javaa rôzne oblasti funkčnosti.

Úplný zoznam podporovaných miestnych nastavení je k dispozícii na webovej stránke Oracle Java Development Kit.

2.7. Predvolené miestne nastavenie

Pri práci s lokalizáciou budeme možno potrebovať vedieť, čo je predvolené Miestne nastavenie na našom JVM inštancia je. Našťastie existuje jednoduchý spôsob, ako to urobiť:

Locale defaultLocale = Locale.getDefault ();

Môžeme tiež určiť predvolené nastavenie Miestne nastavenie vyvolaním podobnej metódy nastavovača:

Locale.setDefault (Locale.CANADA_FRENCH);

Je to obzvlášť dôležité, keď by sme chceli vytvárať JUnit testy, ktoré nezávisia od a JVM inštancia.

3. Čísla a meny

Táto časť sa týka formátovačov čísel a mien, ktoré by mali vyhovovať rôznym konvenciám špecifickým pre miestne nastavenie.

Na formátovanie primitívnych typov čísel (int, dvojitý), ako aj ich objektové ekvivalenty (Celé číslo, Dvojitý), mali by sme použiť NumberFormat triedy a jej statické továrenské metódy.

Pre nás sú zaujímavé dve metódy:

  • NumberFormat.getInstance (miestne miestne nastavenie)
  • NumberFormat.getCurrencyInstance (miestne miestne nastavenie)

Poďme preskúmať ukážkový kód:

Locale usLocale = Locale.US; dvojité číslo = 102300.456d; NumberFormat usNumberFormat = NumberFormat.getInstance (usLocale); assertEquals (usNumberFormat.format (number), "102 300 456");

Ako vidíme, je to také jednoduché ako vytváranie Miestne nastavenie a pomocou neho načítať NumberFormat inštancia a formátovanie vzorového čísla. Môžeme si to všimnúť výstup obsahuje desatinné miesta a tisíc oddeľovačov špecifických pre miestne nastavenie.

Tu je ďalší príklad:

Locale usLocale = Locale.US; BigDecimal number = nový BigDecimal (102_300.456d); NumberFormat usNumberFormat = NumberFormat.getCurrencyInstance (usLocale); assertEquals (usNumberFormat.format (number), "102 300,46 dolárov");

Formátovanie meny zahŕňa rovnaké kroky ako formátovanie čísla. Rozdiel je iba v tom, že formátovač pripojí symbol meny a zaokrúhlenú desatinnú časť na dve číslice.

4. Dátum a čas

Teraz sa dozvieme o formátovaní dátumov a časov, ktoré je pravdepodobne zložitejšie ako formátovanie čísel.

Najskôr by sme mali vedieť, že formátovanie dátumu a času sa v prostredí Java 8 výrazne zmenilo, pretože obsahuje úplne nové Dátum Čas API. Preto sa pozrieme na rôzne triedy formátovacích nástrojov.

4.1. DateTimeFormatter

Od zavedenia Java 8 je hlavnou triedou pre lokalizáciu dátumov a časov DateTimeFormatter trieda. Funguje na triedach, ktoré implementujú TemporalAccessor rozhranie, napríklad LocalDateTime, LocalDate, LocalTime alebo ZonedDateTime. Ak chcete vytvoriť DateTimeFormatter musíme poskytnúť aspoň vzor, ​​a potom Miestne nastavenie Pozrime sa na ukážkový kód:

Locale.setDefault (Locale.US); LocalDateTime localDateTime = LocalDateTime.of (2018, 1, 1, 10, 15, 50, 500); Reťazcový vzor = "dd-MMMM-rrrr HH: mm: ss.SSS"; DateTimeFormatter defaultTimeFormatter = DateTimeFormatter.ofPattern (vzor); DateTimeFormatter deTimeFormatter = DateTimeFormatter.ofPattern (vzor, ​​Locale.GERMANY); assertEquals ("01-január-2018 10:15:50 000", defaultTimeFormatter.format (localDateTime)); assertEquals ("01-január-2018 10:15:50 000", deTimeFormatter.format (localDateTime));

To môžeme vidieť po načítaní DateTimeFormatter všetko, čo musíme urobiť, je zavolať formát () metóda.

Pre lepšie pochopenie by sme sa mali oboznámiť s možnými vzorovými písmenami.

Pozrime sa napríklad na písmená:

Symbol Význam Príklady prezentácie ------ ------- ------------ ------- y rok éry rok 2004; 04 M / L počet mesiacov v mesiaci / text 7; 07; Júl; Júl; J d počet mesiacov v mesiaci 10 H počet hodín dňa (0-23) počet 0 m počet minút v minútach 30 s číslo druhej minúty 55 S zlomok druhej minúty 978

Všetky možné vzorové písmená s vysvetlením nájdete v dokumentácii Java programu DateTimeFormatter.Je potrebné vedieť, že konečná hodnota závisí od počtu symbolov. V príklade je „MMMM“, ktorý vytlačí celý názov mesiaca, zatiaľ čo jediné písmeno „M“ dá číslu mesiaca bez úvodnej nuly.

Dokončiť DateTimeFormatter, pozrime sa, ako môžeme formátovať LocalizedDateTime:

LocalDateTime localDateTime = LocalDateTime.of (2018, 1, 1, 10, 15, 50, 500); ZoneId losAngelesTimeZone = TimeZone.getTimeZone ("Amerika / Los_Angeles"). ToZoneId (); DateTimeFormatter localizedTimeFormatter = DateTimeFormatter .ofLocalizedDateTime (FormatStyle.FULL); Reťazec formattedLocalizedTime = localizedTimeFormatter.format (ZonedDateTime.of (localDateTime, losAngelesTimeZone)); assertEquals ("pondelok 1. januára 2018 10:15:50 PST", formattedLocalizedTime);

Za účelom formátovania LocalizedDateTime, môžeme použiť ofLocalizedDateTime (FormatStyle dateTimeStyle) metóda a poskytnúť vopred definované FormatStyle.

Pre detailnejšiu predstavu o Java 8 Dátum Čas API, máme tu už existujúci článok.

4.2. Formát dátumu a SimpleDateFormatter

Pretože stále je bežné pracovať na projektoch, ktoré využívajú Termíny a Kalendáre, v krátkosti predstavíme možnosti formátovania dátumov a časov pomocou Formát dátumu a SimpleDateFormat triedy.

Poďme analyzovať schopnosti prvého:

GregorianCalendar gregorianCalendar = nový GregorianCalendar (2018, 1, 1, 10, 15, 20); Dátum dátum = gregorianCalendar.getTime (); DateFormat ffInstance = DateFormat.getDateTimeInstance (DateFormat.FULL, DateFormat.FULL, Locale.ITALY); DateFormat smInstance = DateFormat.getDateTimeInstance (DateFormat.SHORT, DateFormat.MEDIUM, Locale.ITALY); assertEquals ("giovedì 1 febbraio 2018 10.15.20 SEČ", ffInstance.format (dátum)); assertEquals ("01/02/18 10.15.20", smInstance.format (dátum));

Formát dátumu pracuje s Termíny a má tri užitočné metódy:

  • getDateTimeInstance
  • getDateInstance
  • getTimeInstance

Všetky majú preddefinované hodnoty Formát dátumu ako parameter. Každá metóda je preťažená, takže prechádzajú Miestne nastavenie je tiež možné. Ak chceme použiť vlastný vzor, ​​ako sa to deje v DateTimeFormatter, môžeme použiť SimpleDateFormat. Pozrime sa na krátky úryvok kódu:

GregorianCalendar gregorianCalendar = nový GregorianCalendar (2018, 1, 1, 10, 15, 20); Dátum dátum = gregorianCalendar.getTime (); Locale.setDefault (nové miestne nastavenie ("pl", "PL")); SimpleDateFormat fullMonthDateFormat = nový SimpleDateFormat ("dd-MMMM-rrrr HH: mm: ss: SSS"); SimpleDateFormat shortMonthsimpleDateFormat = nový SimpleDateFormat ("dd-MM-rrrr HH: mm: ss: SSS"); assertEquals ("01-lutego-2018 10:15:20: 000", fullMonthDateFormat.format (dátum)); assertEquals ("01-02-2018 10:15:20: 000", shortMonthsimpleDateFormat.format (dátum));

5. Prispôsobenie

Z dôvodu niektorých dobrých rozhodnutí o dizajne nie sme viazaní na vzorec formátovania špecifický pre miestne nastavenie a môžeme nakonfigurovať takmer všetky detaily, aby sme boli s výstupom úplne spokojní.

Na prispôsobenie formátovania čísel môžeme použiť DecimalFormat a Symboly DecimalFormat.

Pozrime sa na krátky príklad:

Locale.setDefault (Locale.FRANCE); BigDecimal number = nový BigDecimal (102_300.456d); DecimalFormat zeroDecimalFormat = nový DecimalFormat ("000000000,0000"); DecimalFormat dollarDecimalFormat = nový DecimalFormat ("$ ###, ###. ##"); assertEquals (zeroDecimalFormat.format (number), "000102300,4560"); assertEquals (dollarDecimalFormat.format (number), "102 300,46 dolárov"); 

The DecimalFormat dokumentácia zobrazuje všetky možné znaky vzoru. Všetko, čo teraz potrebujeme vedieť, je, že „000000000 000“ určuje počiatočné alebo koncové nuly, „,“ je oddeľovač tisícov a „.“ je desatinné číslo.

Je tiež možné pridať symbol meny. Nižšie vidíme, že rovnakého výsledku je možné dosiahnuť použitím DateFormatSymbol trieda:

Locale.setDefault (Locale.FRANCE); BigDecimal number = nový BigDecimal (102_300.456d); DecimalFormatSymbols decimalFormatSymbols = DecimalFormatSymbols.getInstance (); decimalFormatSymbols.setGroupingSeparator ('^'); decimalFormatSymbols.setDecimalSeparator ('@'); DecimalFormat separatorsDecimalFormat = nový DecimalFormat ("$ ###, ###. ##"); separatorsDecimalFormat.setGroupingSize (4); separatorsDecimalFormat.setCurrency (Currency.getInstance (Locale.JAPAN)); separatorsDecimalFormat.setDecimalFormatSymbols (decimalFormatSymbols); assertEquals (separatorsDecimalFormat.format (number), "$ 10 ^ [email protected]");

Ako vidíme, Symboly DecimalFormat trieda nám umožňuje určiť akékoľvek formátovanie čísla, aké si dokážeme predstaviť.

Prispôsobiť SimpleDataFormat, môžeme použiť Symboly DateFormat.

Pozrime sa, aká jednoduchá je zmena mien dní:

Dátum dátum = nový GregorianCalendar (2018, 1, 1, 10, 15, 20) .getTime (); Locale.setDefault (nové miestne nastavenie ("pl", "PL")); DateFormatSymbols dateFormatSymbols = nový DateFormatSymbols (); dateFormatSymbols.setWeekdays (nový reťazec [] {"A", "B", "C", "D", "E", "F", "G", "H"}); SimpleDateFormat newDaysDateFormat = nový SimpleDateFormat ("EEEE-MMMM-rrrr HH: mm: ss: SSS", dateFormatSymbols); assertEquals ("F-lutego-2018 10:15:20: 000", newDaysDateFormat.format (dátum));

6. Balíky zdrojov

Nakoniec je rozhodujúcou súčasťou internacionalizácie v JVM je Balík zdrojov mechanizmus.

Účelom a ResourceBundle je poskytnúť aplikáciu s lokalizovanými správami / popismi, ktoré je možné externalizovať do samostatných súborov. Používaniu a konfigurácii balíka zdrojov sa venujeme v jednom z našich predchádzajúcich článkov - sprievodcovi balíkom zdrojov.

7. Záver

Miestne nastavenia a formátovače, ktoré ich využívajú, sú nástroje, ktoré nám pomáhajú vytvárať internacionalizovanú aplikáciu. Tieto nástroje nám umožňujú vytvoriť aplikáciu, ktorá sa dokáže dynamicky adaptovať na jazykové alebo kultúrne nastavenia používateľa bez toho, aby bolo potrebné vytvárať alebo sa dokonca obávať, či Java podporuje Miestne nastavenie.

Vo svete, kde môže byť používateľ kdekoľvek a hovoriť akýmkoľvek jazykom, schopnosť uplatniť tieto zmeny znamená, že naše aplikácie môžu byť intuitívnejšie a pochopiteľnejšie pre viac používateľov na celom svete.

Pri práci s aplikáciami Spring Boot máme tiež vhodný článok o internacionalizácii Spring Boot.

Zdrojový kód tohto tutoriálu s úplnými príkladmi nájdete na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found