Converti java.time.LocalDate nel tipo java.util.Date


372

Voglio convertire java.time.LocalDatein java.util.Datetipo. Perché voglio impostare la data in JDateChooser. O c'è un selettore di date che supporta le java.timedate?



2
LGoodDatePicker utilizza nativamente il pacchetto java.time (alias Java 8 time o JSR-310 . In particolare, LGoodDatePicker utilizza un "java.time.LocalDate" per memorizzare i valori della data. Schermate e una demo si trovano nella homepage del progetto .
BlakeTNC

Risposte:


560
Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

Ciò presuppone che il selettore di date utilizzi il fuso orario predefinito del sistema per trasformare le date in stringhe.


JB Nizet forse Java 8 era in una fase iniziale di sviluppo / rilascio e @ user3509494 lo stava testando in qualche modo.
Russellhoff,

2
È possibile evitare atStartOfDay(), dal momento che cambia il valore della data, come ho capito.
yegor256,

1
@JBNizet la tua risposta non ha molto senso per me, ecco perché ho deciso di chiarire. Perché non lo chiarisci invece di fare commenti inutili?
yegor256,

12
Perché non vedo come e perché avrebbe bisogno di qualche chiarimento. 232 persone hanno votato a favore di questa risposta, trovandola così chiara. Dici che AtartOfDay modifica il valore della data. Non ha senso. atStartOfDay fa quello che dice il javadoc: trasforma un LocalDate in un LocalDateTime, nella stessa data e all'inizio della giornata.
JB Nizet,

2
@cornz Sei sicuro che i tuoi risultati non siano corretti? Se sei in Germania, allora potrebbe essere qualcosa a che fare con il glitch di 6 minuti e 32 secondi nel tempo in Germania, nell'aprile 1893. Vedi timeanddate.com/time/zone/germany/berlin?syear=1850 per alcuni dettagli .
Dawood ibn Kareem,

104

Ecco una classe di utilità che utilizzo per convertire le java.timeclassi più recenti in java.util.Dateoggetti e viceversa:

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

public class DateUtils {

  public static Date asDate(LocalDate localDate) {
    return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
  }

  public static Date asDate(LocalDateTime localDateTime) {
    return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
  }

  public static LocalDate asLocalDate(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
  }

  public static LocalDateTime asLocalDateTime(Date date) {
    return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
  }
}

Modificato in base al commento di @Oliv.


Non sta usando ZoneId.systemDefault()problemi perché i fusi orari cambiano nel corso dell'anno. Quindi se il 1 ° gennaio sono nel fuso orario -05: 00 (centrale), ma il 1 ° luglio sono nel fuso orario -06: 00 (luce del giorno centrale) non causerà risultati inaccurati a causa dell'ora legale tempo?
jhilden,

95

Puoi usare il java.sql.Date.valueOf()metodo come:

Date date = java.sql.Date.valueOf(localDate);

Non è necessario aggiungere qui le informazioni sull'ora e sul fuso orario perché vengono prese in modo implicito.
Vedi LocalDate in java.util.Date e viceversa la conversione più semplice?


Questo è stato perfetto per me, poiché ciò di cui avevo bisogno era passare LocalDate in SQL. Tuttavia, se il tuo formatter data farà qualcosa per il fuso orario prima di formattare la data, potresti ricevere un giorno troppo presto a seconda del fuso orario locale, nel qual caso vorrai invece una delle opzioni di cui sopra.
Tom Dibble,

7
java.sql.Dateè pensato per il livello del database, JDBC, JPA. Il livello Web (o qualsiasi applicazione client) dovrebbe essere assolutamente privo di qualsiasi dipendenza da java.sql.*.
Piccolo

2
@Tiny java.sql.Date risiede in rt.jar. Non ci sono dipendenze esterne. Basta usare le funzionalità della lingua.
George,

2
java.sql.Dateè solo java.util.Datecon il suo tempo impostato, 00:00:00ma il punto di vista progettuale è che java.sql.*non è pensato per un livello frontale con cui i clienti interagiscono come Servlet / JSP. java.util.Datenel lato Java java.sql.Timestampeo qualsiasi altra cosa applicabile java.sql.*nel lato JDBC .
Piccolo

5
Questo è un "orribile hack" secondo java.time. * Autore: stackoverflow.com/questions/33066904/… . In Java 9 le java.sql.*classi avranno una dipendenza separata.
Dherik,

16

java.time ha l'interfaccia temporale che puoi usare per creare oggetti istantanei dalla maggior parte delle classi temporali. Instant rappresenta i millisecondi della sequenza temporale nell'epoca, il riferimento di base per tutte le altre date e orari.

Abbiamo bisogno di convertire la data in un ZonedDateTime, con un ora e una zona, per fare la conversione:

LocalDate ldate = ...;
Instant instant = Instant.from(ldate.atStartOfDay(ZoneId.of("GMT")));
Date date = Date.from(instant);

12

Per creare un java.util.Date da un java.time.LocalDate , devi farlo

  • aggiungere un tempo al LocalDate
  • interpretare la data e l'ora all'interno di un fuso orario
  • ottenere il numero di secondi / millisecondi da allora dall'epoca
  • crea un java.util.Date

Il codice potrebbe apparire come segue:

LocalDate localDate = LocalDate.now();
Date date = new Date(localDate.atStartOfDay(ZoneId.of("America/New_York")).toEpochSecond() * 1000);

1
Typo in zone id (ZoneIf)
assylias

localDate.atStartOfDay () crea un ZonedDateTime, ma non esiste un metodo toEpochSecond () per ZonedDateTime.
Kevin Sadler,

@KevinSadler: il metodo toEpochSecondè ereditato da java.time.chrono.ChronoZonedDateTime. Vedi docs.oracle.com/javase/8/docs/api/java/time/chrono/…
nosid

@nosid Grazie per la correzione. Quando utilizzo il completamento del codice in Eclipse (e toInstance) non è presente come opzione. Ma se lo scrivo per intero sembra essere accettato. Avevo erroneamente concluso che non era un metodo a causa di questo fatto e che non l'avevo visto su Javadoc per ZonedDateTime, poiché è elencato come metodo ereditato, come dici tu. Scusa, per favore accetta un upclick :)
Kevin Sadler,

11

Questo funziona per me:

java.util.Date d = new SimpleDateFormat("yyyy-MM-dd").parse(localDate.toString());

https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html#toString--


6
questo è abbastanza inefficiente
AndresQ

1
La conversione in Instant potrebbe essere prolissa, ma costruire e analizzare una stringa è come andare da New York a Città del Messico passando per Tokyo ...
ehecatl,

1
Sì, non così efficiente, ma la maggior parte delle soluzioni è molto dettagliata. Questo è solo verboso ed è più facile da leggere e capire.
Ceklock,

2
@ehecatl Attenzione ... in futuro NY -> Tokyo -> Città del Messico potrebbe essere eseguita entro un'ora (e);)
Stephan

3

Soluzione di Kotlin:

1) Incolla questa funzione di estensione da qualche parte.

fun LocalDate.toDate(): Date = Date.from(this.atStartOfDay(ZoneId.systemDefault()).toInstant())

2) Usalo e non usarlo mai più.

val myDate = myLocalDate.toDate()

11
Come è semplice "passare a Kotlin"? Questa è una domanda Java.
ehecatl,

1
La conversione di Java LocalDate in Date è un problema comune e fastidioso per qualsiasi sviluppatore JVM. Questa è una soluzione per gli sviluppatori di Kotlin.
Gyoder,

-1
public static Date convertToTimeZone(Date date, String tzFrom, String tzTo) {
    return Date.from(LocalDateTime.ofInstant(date.toInstant(), ZoneId.of(tzTo)).atZone(ZoneId.of(tzFrom)).toInstant());
} 

2
Per favore, spiega la tua soluzione.
Martin Zabel,

-2

Semplice

public Date convertFrom(LocalDate date) {
    return java.sql.Timestamp.valueOf(date.atStartOfDay());
}

-3
java.util.Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());

in che modo la tua risposta è diversa da quella accettata dopo 4 anni? Copia-incolla per ottenere un aumento della reputazione?
Stinger
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.