javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen

7 Internationalisering


7.1 Internationale programmer 122

7.1.1 Formatering af tidspunkter 122

7.1.2 Formatering af tal og beløb 123

7.1.3 Tekstindhold i resursefiler 123

7.1.4 Avanceret: Binære resursefiler 124

7.1.5 Avanceret tekstformatering 125

7.2 Selv bestemme sproget 127

7.2.1 Styre sproget fra kommandolinjen 127

7.2.2 De mulige Locale-objekter 127

7.2.3 Bruge Locale-objekter 128

7.2.4 Avanceret: Sætte standardsprog 128

7.1 Internationale programmer

Når et program skal anvendes af flere kulturer og sprog, opstår behov for, at programtekster, beløb og dato angives i de pågældende landes sprog, og man må i gang med at internationalisere og lokaliseret programmet.

Internationalisering (eng.: Internationalization, også kaldet I18N) består i at gøre programmet sprogneutralt, ved at sørge for at al formatering og fortolkning af tal-, beløbs-, dato- og tidsangivelser sker afhængigt af sproget, og at al sproglig tekst er flyttet til resursefiler.

Lokalisering består i at oversætte resursefilerne til et bestemt sprog.

7.1.1 Formatering af tidspunkter

DateFormat formaterer Date-objekter til strenge (og den anden vej).

import java.text.*;
import java.util.*;
public class BenytDateFormat
{
  public static void main(String arg[])
  {
    DateFormat klformat, datoformat, dkf;
    klformat   = DateFormat.getTimeInstance(DateFormat.MEDIUM);
    datoformat = DateFormat.getDateInstance(DateFormat.FULL);
    dkf = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.SHORT);

    Date tid = new Date();
    System.out.println( tid );
    System.out.println( "Kl   :"+ klformat.format(tid) );
    System.out.println( "Dato :"+ datoformat.format(tid) );
    System.out.println( "Tid  :"+ dkf.format(tid) );
  }
}

Wed Feb 05 14:23:46 GMT+00:00 2003
Kl   :14:23:46
Dato :5. februar 2003
Tid  :05-02-2003 14:23

Læg for det første mærke til, at toString() på Date ikke er lokaliseret. Den bør kun bruges til test-udskrifter og logning og ikke i tekst, som brugeren skal læse.

Ovenstående program er kørt med danske sprogindstillinger. Med amerikanske sprogindstillinger bliver uddata i stedet:

Mon Dec 03 13:27:57 GMT+01:00 2001
Kl: 1:27:57 PM
Dato: Monday, December 3, 2001
Tid: Dec 3, 2001 1:27 PM

Det ses, at det afhænger en del af sproget, præcist hvordan tider bliver formateret (f.eks. er ugedag med i den amerikanske tekst, men ikke i den danske).

Ønsker man som programmør fuld kontrol over, hvordan teksten bliver formateret, må man selv specificere formatet med SimpleDateFormat:

import java.text.*;
import java.util.*;
public class BenytSimpleDateFormat
{
  public static void main(String arg[])
  {
    DateFormat df = new SimpleDateFormat("EEEE 'den' d. MMMM 'år' yyyy.");

    Date tid = new Date();
    System.out.println( df.format(tid) );
  }
}

mandag den 3. december år 2001.

Dermed bliver selve formaterings-strengen sprogspecifik (og den bør lægges ud i en resursefil - se senere). Køres den med amerikanske sprogindstillinger, bliver uddata:

Monday den 3. December år 2001.

7.1.2 Formatering af tal og beløb

På samme måde som med tidsangivelser formateres/fortolkes tal ved at bede om et formateringsobjekt, der klarer netop denne form for tal:

import java.text.*;
public class BenytNumberFormat {
  public static void main(String arg[]) {
    NumberFormat fmt1 = NumberFormat.getInstance();
    NumberFormat fmt2 = NumberFormat.getCurrencyInstance();
    NumberFormat fmt3 = NumberFormat.getPercentInstance();
    double tal = 1234.5678;
    System.out.println( fmt1.format(tal) );
    System.out.println( fmt2.format(tal) );
    System.out.println( fmt3.format(tal) );
  }
}

1.234,568
kr 1.234,57
123.457%

Med amerikanske sprogindstillinger bliver uddata:

1,234.568
$1,234.57
123,457%

7.1.3 Tekstindhold i resursefiler

Programmet BenytDateFormat er halvt internationaliseret, da tidsformateringen korrekt skifter afhængigt af sproget. Der mangler kun strengene "Kl: ", "Dato: " og "Tid: ".

Lad os nu fuldføre internationaliseringen ved at lægge tekstindholdet (strengene) ud i et resursebundt (eng.: resource bundle) med navnet Tekster. Disse kan tilgås fra programmet således:

import java.text.*;
import java.util.*;
public class BenytDateFormatMedResurser
{
  public static void main(String arg[])
  {
    ResourceBundle res = ResourceBundle.getBundle("Tekster");
    DateFormat klformat, datoformat, dkf;
    klformat   = DateFormat.getTimeInstance(DateFormat.MEDIUM);
    datoformat = DateFormat.getDateInstance(DateFormat.FULL);
    dkf = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.SHORT);

    Date tid = new Date();
    System.out.println( res.getString("Kl_")+ klformat.format(tid) );
    System.out.println( res.getString("Dato_")+ datoformat.format(tid) );
    System.out.println( res.getString("Tid_")+ dkf.format(tid) );
  }
}

Kl  : 14:23:50
Dato: 5. februar 2003
Tid : 05-02-2003 14:23

Resursebundtet, der skal ligge i filen Tekster.properties, indeholder teksten i nøgle-værdi-par. Disse vil blive brugt, hvis der ikke findes resursefiler for det pågældende sprog:

Tid_=Tid  \:
Kl_=Kl   \:
Dato_=Dato \:

Køres programmet (på et styresystem indstillet til dansk), fås samme udskrift som før.

Lad os nu lokalisere programmet til engelsk. Det består i, at vi opretter Tekster_en.properties med de engelske tekster:

Tid_=Time       \:
Kl_=Time of day\:
Dato_=Date       \:

Starter vi derefter programmet med engelske sprogindstillinger, får vi uddata:

Time of day : 3:07:28 PM
Date        : Monday, December 3, 2001
Time        : Dec 3, 2001 3:07 PM

Hvordan der søges efter resurser

Når programmet skal finde en programtekst ud fra sprogindstillingerne, sker det ved først at kigge i den mest specifikke resursefil. Hvis programteksten ikke findes der, kigges i en mere generel resursefil og til sidst i den mest generelle.

For eksempel vil resurser til sproget fr_CA (canadisk fransk) blive søgt

  1. først i Tekster_fr_CA.properties

  2. dernæst i Tekster_fr.properties

  3. og sidst i Tekster.properties

7.1.4 Avanceret: Binære resursefiler

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

7.1.5 Avanceret tekstformatering

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

7.2 Selv bestemme sproget

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.

7.2.1 Styre sproget fra kommandolinjen

Ved opstart af et program opretter Java et Locale-objekt, der svarer til sprogindstillingerne på maskinen.

På et UNIX-system gøres det ud fra miljøvariablen LC_CTYPE eller LC_ALL. Den amerikanske udskrift til BenytDateFormat er f.eks. fundet med UNIX-kommandoen:

  LC_CTYPE=en java BenytDateFormat

7.2.2 De mulige Locale-objekter

Man kan undersøge, hvilke Locale-objekter der er tilgængelige, ved at kalde klassemetoden Locale.getAvailableLocales():

import java.text.*;
import java.util.*;
public class MuligeSprog
{
  public static void main(String arg[])
  {
    Locale[] l = Locale.getAvailableLocales();
    for (int i=0; i<l.length; i++) System.out.print(l[i]+" ");
    System.out.println( );
  }
}

ar ar_AE ar_BH ar_DZ ar_EG ar_IQ ar_JO ar_KW ar_LB ar_LY ar_MA ar_OM ar_QA ar_SA 
ar_SD ar_SY ar_TN ar_YE be be_BY bg bg_BG ca ca_ES cs cs_CZ da da_DK de de_AT
de_CH de_DE de_LU el el_GR en_AU en_CA en_GB en_IE en_IN en_NZ en_ZA es es_BO
es_AR es_CL es_CO es_CR es_DO es_EC es_ES es_GT es_HN es_MX es_NI es_PA es_PE
es_PR es_PY es_SV es_UY es_VE et et_EE fi fi_FI fr fr_BE fr_CA fr_CH fr_FR fr_LU
hr hi_IN hr_HR hu hu_HU is is_IS it it_CH it_IT iw iw_IL ja ja_JP ko ko_KR lt
lt_LT lv lv_LV mk mk_MK nl nl_BE nl_NL no no_NO no_NO_NY pl pl_PL pt pt_BR pt_PT
ro ro_RO ru ru_RU sh sh_YU sk sk_SK sl sl_SI sq sq_AL sr sr_YU sv sv_SE th th_TH
th_TH_TH tr tr_TR uk uk_UA zh zh_CN zh_HK zh_TW en en_US

Localet består af tre dele:

Eksempler:

fr_BE: Fransk i Belgien

fr_BE_EURO: Fransk i Belgien med euro-valuta

fr_CA: Fransk i Canada

fr_FR: Fransk i Frankrig

fr_LU: Fransk i Luxembourg

7.2.3 Bruge Locale-objekter

Ønsker man finkornet kontrol over, hvilket sprog der anvendes, kan man oprette et Locale-objekt selv, og dette objekt kan så bruges til at fremskaffe formateringsobjekter til det pågældende sprog:

import java.text.*;
import java.util.*;
public class BenytDateFormat2
{
  public static void main(String arg[])
  {
    DateFormat klformat, datoformat;

    Locale fransk = new Locale("fr","FR");
    klformat   = DateFormat.getTimeInstance(DateFormat.SHORT,fransk);
    datoformat = DateFormat.getDateInstance(DateFormat.LONG, fransk);

    Date tid = new Date();
    System.out.println( "Kl:   "+ klformat.format(tid) );
    System.out.println( "Dato: "+ datoformat.format(tid) );
  }
}

Kl:   14:23
Dato: 5 février 2003

7.2.4 Avanceret: Sætte standardsprog

Dette afsnit er ikke omfattet af Åben Dokumentslicens.
Du skal købe bogen for at måtte læse dette afsnit.
Jeg erklærer, at jeg allerede har købt bogen
Jeg lover at anskaffe den i nær fremtid.
javabog.dk  |  << forrige  |  indhold  |  næste >>  |  programeksempler  |  om bogen
http://javabog.dk/ - af Jacob Nordfalk.
Licens og kopiering under Åben Dokumentlicens (ÅDL) hvor intet andet er nævnt (71% af værket).

Ønsker du at se de sidste 29% af dette værk (362838 tegn) skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.