En guide til SimpleDateFormat

1. Introduksjon

I denne opplæringen tar vi en grundig omvisning i SimpleDateFormat klasse.

Vi tar en titt på enkel instantieringog formateringsstiler samt nyttige metoder klassen utsetter for håndtering av lokaliteter og tidssoner.

2. Enkel Instantiering

La oss først se på hvordan du kan starte en ny SimpleDateFormat gjenstand.

Det er fire mulige konstruktører - men i tråd med navnet, la oss holde ting enkelt. Alt vi trenger for å komme i gang er en String representasjon av et datomønster vi ønsker.

La oss starte med et dash-skilt datomønster slik:

"dd-MM-åååå"

Dette vil formatere en dato som starter med gjeldende dag i måneden, gjeldende måned i året og til slutt inneværende år. Vi kan teste vår nye formater med en enkel enhetstest. Vi starter et nytt SimpleDateFormat innvende, og send inn en kjent dato:

SimpleDateFormat formatter = ny SimpleDateFormat ("dd-MM-åååå"); assertEquals ("24-05-1977", formatter.format (ny dato (233345223232L))); 

I koden ovenfor er formatering konverterer millisekunder som long inn i en menneskelig lesbar dato - 24. mai 1977.

2.1. Fabrikkmetoder

Selv om SimpleDateFormat er en praktisk klasse for raskt å lage en datoformatering, Vi oppfordres til å bruke fabrikkmetodene på DateFormat klassegetDateFormat (), getDateTimeFormat (), getTimeFormat ().

Ovenstående eksempel ser litt annerledes ut når du bruker disse fabrikkmetodene:

DateFormat formatter = DateFormat.getDateInstance (DateFormat.SHORT); assertEquals ("5/24/77", formatter.format (ny dato (233345223232L)));

Som vi kan se ovenfra, bestemmes antall formateringsalternativer på forhånd av feltene på DateFormat klasse. Dette i stor grad begrenser våre tilgjengelige alternativer for formatering det er grunnen til at vi vil holde oss til SimpleDateFormat i denne artikkelen.

2.2. Trådsikkerhet

JavaDoc for SimpleDateFormat uttrykkelig sier:

Datoformater blir ikke synkronisert. Det anbefales å lage separate formatforekomster for hver tråd. Hvis flere tråder får tilgang til et format samtidig, må det synkroniseres eksternt.

SimpleDateFormat tilfeller er ikke trådsikre, og vi bør bruke dem nøye i samtidige miljøer.

Den beste tilnærmingen for å løse dette problemeter å bruke dem i kombinasjon med en Trådlokal. På denne måten ender hver tråd opp med sin egen SimpleDateFormat forekomst, og mangel på deling gjør programmet trådsikkert:

private final ThreadLocal formatter = ThreadLocal .withInitial (() -> new SimpleDateFormat ("dd-MM-åååå"));

Argumentet for med Initial metoden er en leverandør av SimpleDateFormat tilfeller. Hver gang Trådlokal trenger å opprette en forekomst, vil den bruke denne leverandøren.

Da kan vi bruke formateringen via Trådlokal forekomst:

formatter.get (). format (dato)

De ThreadLocal.get () metoden initialiserer SimpleDateFormat for den gjeldende tråden først, og deretter gjenbruker den forekomsten.

Vi kaller denne teknikken trådinneslutning når vi begrenser bruken av hver forekomst til en bestemt tråd.

Det er to andre tilnærminger for å takle det samme problemet:

  • Ved hjelp av synkronisert blokker eller ReentrantLocks
  • Opprette kaste forekomster av SimpleDateFormat på etterspørsel

Begge disse tilnærmingene anbefales ikke: Førstnevnte får en betydelig ytelseshit når påstanden er høy, og sistnevnte skaper mange gjenstander, og legger press på søppeloppsamlingen.

Det er verdt å nevne det, siden Java 8, en ny DateTimeFormatter klasse er innført. Den nye DateTimeFormatter klasse er uforanderlig og trådsikker. Hvis vi jobber med Java 8 eller nyere, bruker vi det nye DateTimeFormatter klasse anbefales.

3. Parsing Datoer

SimpleDateFormat og DateFormat ikke bare tillate oss å formatere datoer - men vi kan også reversere operasjonen. Bruker analysere metoden, kan vi skriv inn String representasjon av en dato og returnere Dato objekt ekvivalent:

SimpleDateFormat formatter = ny SimpleDateFormat ("dd-MM-åååå"); Date myDate = new Date (233276400000L); Date parsedDate = formatter.parse ("24-05-1977"); assertEquals (myDate.getTime (), parsedDate.getTime ());

Det er viktig å merke seg her at mønsteret som leveres i konstruktøren, skal ha samme format som datoen som ble analysert bruker analysere metode.

4. Dato-tid mønstre

SimpleDateFormat leverer et stort utvalg av forskjellige alternativer når du formaterer datoer. Mens hele listen er tilgjengelig i JavaDocs, la oss utforske noen av de mest brukte alternativene:

BrevDatokomponentEksempel
MMåned12; Des
yår94
ddag23; Man
Htime03
mminutt57

De utdata som returneres av datokomponenten, avhenger også sterkt av antall tegn som brukes innen String. La oss for eksempel ta juni måned. Hvis vi definerer datostrengen som:

"MM"

Så vil resultatet vårt vises som tallkoden - 06. Hvis vi legger til en annen M i datostrengen:

"MMM"

Så vises den resulterende formaterte datoen som ordet Jun.

5. Bruke lokaler

De SimpleDateFormat klasse også støtter et bredt spekter av lokaliteter som stilles inn når konstruktøren kalles.

La oss praktisere dette ved å formatere en dato på fransk. Vi vil instantiere en SimpleDateFormat gjenstand mens du leverer Lokalitet. FRANS til konstruktøren.

SimpleDateFormat franceDateFormatter = ny SimpleDateFormat ("EEEEE dd-MMMMMMM-åååå", Locale.FRANCE); Date myWednesday = new Date (1539341312904L); assertTrue (franceDateFormatter.format (myWednesday) .startsWith ("vendredi"));

Ved å oppgi en gitt dato, onsdag ettermiddag, kan vi hevde at vår franceDateFormatter har riktig formatert datoen. Den nye datoen starter riktig med Vendredi -Fransk for onsdag!

Det er verdt å merke seg litt gotcha i Locale-versjonen av konstruktøren - mens mange lokaliteter støttes, er ikke full dekning garantert. Oracle anbefaler å bruke fabrikkmetodene på DateFormat klasse for å sikre lokal dekning.

6. Endring av tidssoner

Siden SimpleDateFormat utvider DateFormat klasse, kan vi også manipulere tidssonen ved hjelp av setTimeZone metode. La oss ta en titt på dette i aksjon:

Dato nå = ny dato (); SimpleDateFormat simpleDateFormat = ny SimpleDateFormat ("EEEE dd-MMM-åå HH: mm: ssZ"); simpleDateFormat.setTimeZone (TimeZone.getTimeZone ("Europa / London")); logger.info (simpleDateFormat.format (nå)); simpleDateFormat.setTimeZone (TimeZone.getTimeZone ("America / New_York")); logger.info (simpleDateFormat.format (nå));

I eksemplet ovenfor leverer vi det samme Dato til to forskjellige tidssoner på samme SimpleDateFormat gjenstand. Vi har også lagt til ‘Z’ karakter til slutten av mønsteret String for å indikere tidssoneforskjellene. Resultatet fra format metoden logges deretter for brukeren.

Når vi treffer løp, kan vi se gjeldende tider i forhold til de to tidssonene:

INFO: Fredag ​​12-okt-18 12: 46: 14 + 0100 INFO: Fredag ​​12-oktober-18 07: 46: 14-0400

7. Oppsummering

I denne opplæringen har vi tatt et dypt dykk inn i komplikasjonene til SimpleDateFormat.

Vi har sett på hvordan øyeblikkelig SimpleDateFormat samt hvordan mønster String påvirker hvordan datoen formateres.

Vi lekte med endre lokalitet av utgangen String før du endelig eksperimenterer med bruker tidssoner.

Som alltid finner du fullstendig kildekode på GitHub.


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