24.5. Formatering af datoer og klokkeslæt

Date-objekter repræsenterer datoer og klokkeslæt. Dette afsnit går i dybden med de lokalafhængige klasser java.text.DateFormat og java.text.SimpleDateFormat som er velegnet til at formattere Date-objekter.

24.5.1. Prædefineret formater

Klassen DateFormat indeholder en række statiske fabriksmetoder, som returner specialiseret formateringsobjekter. Seks af disse er

getDateInstance(int style)
getDateInstance(int style, Locale aLocale)
getTimeInstance(int style)
getTimeInstance(int style, Locale aLocale)
getDateTimeInstance(int dateStyle, int timeStyle)
getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale)

Metoderne tager imod en eller flere style-parametre, som anvendes til at angive længden af formateringsresultatet. De mulige værdier er defineret som konstanter i DateFormat-klassen.

Det præcise resultat afhænger af lokalindstillingen. Hvis vi i det ovenstående havde brugt en dansk lokalindstilling så ville der ikke være nogen synlig forskel på brugen af LONG og FULL.

Her er et simpelt eksempel, der viser brugen af DateFormat med den globale lokalindstilling.

import java.text.*;
import java.util.*;

public class DateFormatExample
{
  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) );
  }
}

Kørsel af ovenstående program med dansk lokalindstilling (da_DK) giver

Mon Dec 03 13:28:06 GMT+01:00 2001
Kl:   13:28:06
Dato: 3. december 2001
Tid:  03-12-2001 13:28

Hvis lokalindstillingen er amerikansk (en_US) så fås imidlertid

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

Læg i øvrigt mærke til at Date-objektets toString()-metode ikke er lokaliseret. Den bør kun bruges til testudskrifter og logning, og ikke i tekst som brugeren skal læse (med mindre du bevidst ønsker at irritere ham/hende).

24.5.2. Egne formater

Ønsker man som programmør større kontrol over hvordan datoen bliver formateret så må man selv specificere formatet med SimpleDateFormat.

Lad os starte ud med et eksempel.

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) );
  }
}

Kørsel af ovenstående program med dansk lokalindstilling giver

mandag den 10. december år 2001.

En tilsvarende kørsel af programmet med amerikansk lokalindstilling giver

Monday den 10. December ?r 2001.

Ud fra eksemplet ses at formateringsresultatet afhænger af to faktorer: lokalindstillingen samt argumentet angivet til SimpleDateFormats konstruktør. Argumentet angiver et mønster, som angiver hvordan dato- og klokkeslætformateringen logisk bør tage sig ud. Dato- og klokkeslætformater specificeres ved hjælp af bogstaverne a-z og A-Z som har en speciel betydning så længe de ikke er omgivet af apostroffer. F.eks. dækker M over måneden i et år, mens E dækker over dagen i en uge. Antallet af gange et bogstav gentages er ikke helt uden betydning. Gentages M fire gange som i eksemplet så skrives måneden som en tekst, f.eks. 'december', men vises den kun en gang så skrives måneden som et tal, f.eks. 12. Bemærk at konstanterne SHORT, MEDIUM, LONG og FULL i DateFormat-klassen afspejler dette.

I skrivende stund er det ikke alle bogstaver, der har fået tillagt en betydning. Nedenstående tabel viser dem som findes i JDK 1.4. En lignende tabel findes også i API-dokumentationen for SimpleDateFormat.

Tabel 24-1. Dato og klokkeslætmønstre

Tegn Betydning Eksempler med dansk lokalindstilling (1-4 ens)
G Tidsregningbetegnelse AD, AD, AD, AD
y År 02, 02, 02, 2002
M Måneden i et år 6, 06, jun, juni
w Ugen i et år 24, 24, 024, 0024
W Ugen i en måned 2, 02, 002, 0002
D Dagen i et år 162, 162, 162, 0162
d Dagen i en måned 11, 11, 011, 0011
F Ugedagen i en måned 2, 02, 002, 0002
E Dagen i en uge ti, ti, ti, tirsdag
a Am/pm PM, PM, PM, PM
H Timen i en dag (0-23) 19, 19, 019, 0019
k Timen i en dag (1-24) 19, 19, 019, 0019
K Timen i am/pm (0-11) 7, 07, 007, 0007
h Timen i am/pm (1-12) 7, 07, 007, 0007
m Minuttet i en time 49, 49, 049, 0049
s Sekundet i et minut 22, 22, 022, 0022
S Millisekund 689, 689, 689, 0689
z Tidszone (Generel) CEST, CEST, CEST, Central European Summer Time
Z Tidszone (RFC 822) +0200, +0200, +0200, +0200

Ugedagen i en måned kræver en kort forklaring. Hvis datoen er tirsdag den 11. maj 2002, så fortæller den os at det er den 2. tirsdag i maj måned 2002. Er datoen derimod lørdag den 15. maj 2002 så fortæller den os at det er den 3. lørdag i maj måned.