java - util - localdatetime to date



Converti java.util.Date a che tipo "java.time"? (1)

Sì, dovresti sicuramente usare il framework java.time ogni volta che è possibile.

Evita le vecchie lezioni di data-ora

Le vecchie classi di data e ora tra cui java.util.Date , java.util.Calendar e java.text.SimpleTextFormat e simili hanno dimostrato di essere mal progettate, confuse e problematiche . Evitalo dove puoi. Ma quando devi interagire con questi vecchi tipi, puoi convertire tra vecchio e nuovo.

Continua a leggere per un'introduzione di base, un po 'troppo semplificata, per orientarti nello spostamento avanti e indietro tra le vecchie e le nuove lezioni di data-ora.

java.time

Il framework java.time è definito da JSR 310 , ispirato alla libreria Joda-Time grande successo ed esteso dal progetto ThreeTen-Extra . La maggior parte della funzionalità è stata ThreeTen-Backport Java 6 e 7 nel progetto ThreeTen-Backport , con un ulteriore adattamento per Android nel progetto ThreeTenABP .

Quale tipo di java.time corrisponde a java.util.Date ? Bene, un oggetto java.util.Date rappresenta fondamentalmente un momento sulla timeline in UTC, una combinazione di data e ora del giorno. Possiamo tradurlo in uno qualsiasi dei diversi tipi in java.time. Ognuno è discusso di seguito. Si noti che alcuni nuovi metodi sono stati aggiunti alle vecchie classi di data e ora per facilitare le conversioni.

Instant

Il blocco predefinito in java.time è un Instant , un momento sulla timeline in UTC con una risoluzione di nanoseconds .

In generale, dovresti eseguire gran parte della tua logica aziendale in UTC. In tale lavoro, Instant sarà usato frequentemente. Passa attorno agli oggetti Instant , applicando un fuso orario solo per la presentazione a un utente. Quando è necessario applicare un offset o un fuso orario, utilizzare i tipi trattati di seguito.

Da java.util.Date a Instant

Dato che sia Instant che java.util.Date sono un momento nella timeline in UTC, possiamo facilmente passare da un java.util.Date a un Instant . La vecchia classe ha acquisito un nuovo metodo, java.util.Date::toInstant .

Instant instant = myUtilDate.toInstant();

Puoi andare nell'altra direzione, da Instant a java.util.Date . Ma potresti perdere informazioni sul secondo frazionario. Un Instant traccia i nanoseconds , per un massimo di nove cifre dopo la virgola decimale, ad esempio 2016-01-23T12:34:56.123456789Z . Sia java.util.Date che .Calendar sono limitati a milliseconds , per un massimo di tre cifre dopo la virgola decimale, ad esempio 2016-01-23T12:34:56.123Z . In questo esempio, passando da Instant a Date intende il troncamento del 456789 .

java.util.Date myUtilDate = java.util.Date.from( instant );

Da java.util.Calendar a Instant

Che dire di un java.util.Calendar invece di un java.util.Date ? All'interno dell'oggetto del Calendar , la data / ora viene tracciata come un conteggio di milliseconds dall'epoca di riferimento dell'epoca del primo momento del 1970 in UTC ( 1970-01-01T00:00:00.0Z ). Quindi questo valore può essere convertito facilmente in un Instant .

Instant instant = myUtilCalendar.toInstant() ;

Da java.util.GregorianCalendar a ZonedDateTime

Ancora meglio, se il tuo oggetto java.util.Calendar è in realtà un java.util.GregorianCalendar puoi facilmente andare direttamente a ZonedDateTime . Questo approccio ha il vantaggio di mantenere le informazioni sul fuso orario incorporato.

Downcast interface di Calendar alla classe concreta di GregorianCalendar . Quindi chiama il toZonedDateTime e from metodi per andare avanti e indietro.

if( myUtilCalendar instanceof GregorianCalendar ) {
    GregorianCalendar gregCal = (GregorianCalendar) myUtilCalendar; // Downcasting from the interface to the concrete class.
    ZonedDateTime zdt = gregCal.toZonedDateTime();  // Create `ZonedDateTime` with same time zone info found in the `GregorianCalendar`
end if 

Andando nella direzione opposta ...

    java.util.Calendar myUtilCalendar = java.util.GregorianCalendar.from( zdt ); // Produces an instant of `GregorianCalendar` which implements `Calendar` interface.

Come discusso sopra, fai attenzione che potresti perdere informazioni sulla frazione di secondo . I nanoseconds nel tipo java.time ( ZonedDateTime ) vengono troncati in milliseconds nel .Calendar / .GregorianCalendar .

OffsetDateTime

Da un Instant possiamo applicare un offset-from-UTC per spostarci in un tempo di wall-clock per alcune località. Un offset è un numero di ore, e possibilmente minuti e secondi, prima di UTC (verso est) o dietro UTC (verso ovest). La classe ZoneOffset rappresenta questa idea. Il risultato è un oggetto OffsetDateTime .

ZoneOffset offset = ZoneOffset.of( "-04:00" ); 
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );

Puoi andare nell'altra direzione, da OffsetDateTime a java.util.Date . Estrai un Instant e poi procedi come abbiamo visto nel codice sopra. Come discusso sopra, qualsiasi nanoseconds viene troncato in milliseconds ( perdita di dati ).

java.util.Date myUtilDate = java.util.Date.from( odt.toInstant() );

ZonedDateTime

Meglio ancora, applica un fuso orario completo. Un fuso orario è un offset più regole per la gestione delle anomalie come l' ora legale (DST) .

Applicando un ZoneId ottiene un oggetto ZonedDateTime . Utilizzare un nome di fuso orario appropriato (continente / regione). Non usare mai le abbreviazioni di 3-4 lettere comunemente viste come EST o IST quanto non sono né standardizzate né uniche.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

Puoi andare nell'altra direzione, da un ZonedDateTime a un java.util.Date . Estrai un Instant e poi procedi come abbiamo visto nel codice sopra. Come discusso sopra, qualsiasi nanoseconds viene troncato in milliseconds ( perdita di dati ).

java.util.Date myUtilDate = java.util.Date.from( zdt.toInstant() );

E abbiamo visto più in alto che un ZonedDateTime può essere convertito in un GregorianCalendar .

LocalDate

A volte potresti desiderare un valore solo per la data, senza orario e senza fuso orario. Per questo, usa un oggetto java.time.LocalDate .

Vedere questa domanda per ulteriori discussioni, convertire java.util.Date in java.time.LocalDate , in particolare questa risposta scritta dall'uomo principale dietro l'invenzione di Joda-Time e java.time.

La chiave è passare attraverso ZonedDateTime (come generato nel codice sopra). Abbiamo bisogno di un fuso orario per determinare una data. La data varia in tutto il mondo, con un nuovo giorno che sorge all'inizio di est. Ad esempio, dopo la mezzanotte a Parigi è un nuovo giorno mentre ancora "ieri" a Montréal. Pertanto, mentre un LocalDate non contiene un fuso orario, è necessario un fuso orario per determinare un LocalDate .

LocalDate localDate = zdt.toLocalDate();

Convertire nella direzione LocalDate da LocalDate a una data-ora significa inventare un momento della giornata. Puoi scegliere qualsiasi momento del giorno che abbia senso nel tuo scenario aziendale. Per molte persone, il primo momento della giornata ha un senso. Potresti essere tentato di codificare il primo momento come l'ora 00:00:00.0 . In alcuni fusi orari, tale orario potrebbe non essere valido come primo momento a causa dell'ora legale (DST) o di altre anomalie. Quindi lascia che java.time determini l'ora corretta con una chiamata a atStartOfDay .

ZonedDateTime zdt = localDate.atStartOfDay( zoneId );

LocalTime

In rare occasioni potresti volere solo un momento della giornata senza una data e senza un fuso orario. Questo concetto è rappresentato dalla classe LocalTime . Come discusso sopra con LocalDate , abbiamo bisogno di un fuso orario per determinare un LocalTime anche se l'oggetto LocalTime non contiene (non "ricorda") quel fuso orario. Quindi, di nuovo, passiamo attraverso un oggetto ZonedDateTime ottenuto da un Instant come visto sopra.

LocalTime localTime = zdt.toLocalTime();

LocalDateTime

Come per gli altri due tipi di Local… , a LocalDateTime non sono assegnati fuso orario né offset. Come tale, puoi raramente usarlo . Ti dà un'idea approssimativa di una data, ma non è un punto sulla timeline. Utilizzare questo se si intende una data generale e un po 'di tempo che potrebbe essere applicato a un fuso orario.

Ad esempio, "Natale inizia quest'anno" sarà il 2016-12-25T00:00:00.0 . Notare la mancanza di qualsiasi offset o fuso orario in quella rappresentazione testuale di un LocalDateTime . Il Natale inizia prima a Delhi, in India, piuttosto che a Parigi, in Francia, e più tardi ancora a Montréal Québec, in Canada. Applicare il fuso orario di ognuna di queste aree produrrebbe un momento diverso sulla timeline.

LocalDateTime ldt = zdt.toLocalDateTime();

Ho un oggetto java.util.Date o un oggetto java.util.Calendar . Come posso convertirlo nel tipo giusto nel framework java.time ?

Ho sentito che ora dovremmo fare la maggior parte della nostra logica di business con i tipi java.time. Quando si lavora con il vecchio codice non ancora aggiornato per java.time, devo essere in grado di convertire avanti e indietro. Quali tipi di mappe sono in java.util.Date o java.util.Calendar ?





java-time