Konverter java.util.Date til java.time.LocalDate
Hva er den beste måten å konvertere et java.util.Date
-objekt til det nye JDK 8/JSR-310 java.time.LocalDate
?
Date input = new Date();
LocalDate date = ???
462
3
Kort svar.
Forklaring
Til tross for navnet representerer
java.util.Date
et øyeblikk på tidslinjen, ikke endato
. De faktiske dataene som er lagret i objektet, er en "lang" telling av millisekunder siden 1970-01-01T00:00Z (midnatt ved begynnelsen av 1970 GMT/UTC).Den tilsvarende klassen til
java.util.Date
i JSR-310 erInstant
, og det finnes derfor en praktisk metodetoInstant()
for å foreta konverteringen:En
java.util.Date
-instans har ikke noe begrep om tidssone. Dette kan virke rart hvis du kallertoString()
på enjava.util.Date
, forditoString
er relativ til en tidssone. Men den metoden bruker faktisk Javas standard tidssone i farten for å gi strengen. Tidssonen er ikke en del av den faktiske tilstanden tiljava.util.Date
.En
Instant
inneholder heller ingen informasjon om tidssonen. For å konvertere fra enInstant
til en lokal dato er det derfor nødvendig å angi en tidssone. Dette kan være standardsonen -ZoneId.systemDefault()
- eller det kan være en tidssone som applikasjonen din kontrollerer, for eksempel en tidssone fra brukerinnstillingene. BrukatZone()
-metoden for å bruke tidssonen:En
ZonedDateTime
inneholder tilstand bestående av lokal dato og tid, tidssone og forskyvning fra GMT/UTC. Som sådan kan datoen -LocalDate
- enkelt hentes ut ved hjelp avtoLocalDate()
:Java 9-svar
I Java SE 9 er det lagt til en ny metode som forenkler denne oppgaven noe:
Dette nye alternativet er mer direkte, skaper mindre søppel, og bør derfor fungere bedre.
En bedre måte er:
Fordeler med denne versjonen:
Fungerer uansett om input er en forekomst av
java.util.Date
eller dens underklassejava.sql.Date
(i motsetning til @JodaStephens måte). Dette er vanlig med JDBC-opprinnede data.java.sql.Date.toInstant()
kaster alltid et unntak.det' er det samme for JDK8 og JDK7 med JSR-310 backport
Jeg personlig bruker en verktøyklasse (men dette er ikke backport-kompatibelt):
Metoden
asLocalDate()
her er nullsikker, brukertoLocalDate()
, hvis input erjava.sql.Date
(den kan overstyres av JDBC-driveren for å unngå tidssoneproblemer eller unødvendige beregninger), ellers brukes metoden ovenfor.Hvis du bruker Java 8, er @JodaStephens svar åpenbart det beste. Men hvis du jobber med JSR-310 backport, må du dessverre gjøre noe som dette: