Come convertire java.sql.timestamp in LocalDate (java8) java.time?


Risposte:


196

Tu puoi fare:

timeStamp.toLocalDateTime().toLocalDate();

Nota che timestamp.toLocalDateTime() utilizzerà il Clock.systemDefaultZone()fuso orario per effettuare la conversione. Questo può o non può essere quello che vuoi.


1
È stato aggiunto in Java 8.
assylias

54
Solo una nota, il timestamp.toLocalDateTime()metodo utilizzerà il fuso orario systemDefault per effettuare la conversione. Questo può o non può essere quello che vuoi.
jacobhyphenated

1
@jacobhyphenated per favore posta la risposta utilizzando il fuso orario esplicito. Grazie!
user482745

Il commento di @ jacobhyphenated è estremamente importante qui, da cui il numero di voti positivi. Vedi la mia risposta per i dettagli stackoverflow.com/a/57101544/2032701
Ruslan

@jacobhyphenated, LocalDateTimeutilizza sempre il fuso orario predefinito dal sistema. Questo è ciò che significa "Locale" nel suo nome.
M. Prokhorov

21

La risposta accettata non è l'ideale, quindi ho deciso di aggiungere i miei 2 centesimi

timeStamp.toLocalDateTime().toLocalDate();

è una cattiva soluzione in generale , non sono nemmeno sicuro del motivo per cui hanno aggiunto questo metodo al JDK in quanto rende le cose davvero confuse facendo una conversione implicita utilizzando il fuso orario del sistema. Di solito quando si usano solo classi di data java8 il programmatore è costretto a specificare un fuso orario che è una buona cosa.

La buona soluzione è

timestamp.toInstant().atZone(zoneId).toLocalDate()

Dove zoneId è il fuso orario che si desidera utilizzare, che in genere è ZoneId.systemDefault () se si desidera utilizzare il fuso orario del sistema o un fuso orario codificato come ZoneOffset.UTC

L'approccio generale dovrebbe essere

  1. Liberati delle nuove classi di data java8 usando una classe che è direttamente correlata, ad esempio java.time.Instant è direttamente correlato a java.sql.Timestamp , cioè non sono necessarie conversioni di fuso orario tra di loro.
  2. Usa i metodi ben progettati in questa classe java8 per fare la cosa giusta. Nel nostro caso atZone (zoneId) ha reso esplicito che stiamo facendo una conversione e utilizzando un particolare fuso orario per essa.

1
Non sono d'accordo. Il timestamp (e anche la data) non hanno informazioni sulla zona. LocalDate non dispone di informazioni sulla zona, quindi i due sono equivalenti. La conversione tra di loro può essere eseguita indipendentemente da qualsiasi zona particolare. La conversione in ZonedDateTime prima della conversione in LocalDate aggiunge un fuso orario e poi lo toglie di nuovo: è molto più probabile che si verifichi un brutto errore, difficile da trovare, in questo modo.
AutomatedMike

5
@AutomatedMike Timestamp (e anche Date) rappresentano un punto nel tempo in UTC. LocalDate non rappresenta un punto nel tempo, ma piuttosto un tempo come si vede su un orologio da parete. Si prega di leggere i loro javadoc. "La conversione tra di loro può essere eseguita indipendentemente da qualsiasi zona particolare" - non è vero , il nuovo Timestamp (0L) .toLocalDateTime () restituisce "1970-01-01T03: 00" per il mio fuso orario di Mosca. Il risultato potrebbe essere diverso per il tuo fuso orario.
Ruslan

1
@AutomatedMike Anche se si spoglia il tempo eseguendo toLocalDate () è facile dimostrare che il giorno può essere sbagliato se Timestamp aveva un orario intorno a mezzanotte, ad esempio new Timestamp (1000 * 60 * 60 * 23) .toLocalDateTime (). ToLocalDate () restituisce "1970-01-02" per il mio fuso orario di Mosca quando è "1970-01-01" in UTC.
Ruslan

1
@AutomatedMike "aggiunge un fuso orario e poi lo toglie di nuovo" - il punto non è aggiungere e rimuovere un fuso orario, ma piuttosto convertire tra diverse nozioni utilizzando un fuso orario esplicito . Questo è in contrasto con gli esempi dei miei due commenti precedenti in cui un fuso orario viene applicato implicitamente .
Ruslan

7

Espanderò leggermente la risposta di @assylias per tenere conto del fuso orario. Esistono almeno due modi per ottenere LocalDateTime per un fuso orario specifico.

È possibile utilizzare il fuso orario setDefault per l'intera applicazione. Dovrebbe essere chiamato prima di qualsiasi timestamp -> java.time conversione:

public static void main(String... args) {
    TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
    TimeZone.setDefault(utcTimeZone);
    ...
    timestamp.toLocalDateTime().toLocalDate();
}

Oppure puoi usare la catena toInstant.atZone:

timestamp.toInstant()
        .atZone(ZoneId.of("UTC"))
        .toLocalDate();
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.