2015-09-29 5 views
9

Sto pensando di utilizzare la nuova API java 8 Date Time. Ho cercato un po 'su google e ho trovato jodaTime come buona scelta per java, ma sono comunque interessato a vedere come funziona questa nuova API.La nuova Java Date Time API di Java 8 si occupa di DST?

Sto memorizzando tutto il tempo in valori UTC nel mio archivio dati e li convertirò in valore specifico del fuso orario locale in base al fuso orario dell'utente. Posso trovare molti articoli che mostrano come utilizzare la nuova API Java Date Time. Tuttavia non sono sicuro che l'API si prenderà cura delle modifiche all'ora legale? O abbiamo un modo migliore di gestire la data?

Sto solo imparando la nuova API Date, quindi ho pensato di ascoltare i tuoi pensieri sulla gestione di DateTime e visualizzarlo sulla base di TimeZone degli utenti.

+3

In breve: sì, l'ora legale è a carico. L'API di data e ora Java 8 è stata creata in base al tempo di Joda. –

+1

@Raja Correggerò i tuoi termini per evitare confusione ... "Locale" nel lavoro data-ora significa "per qualsiasi località", come in "Natale inizia a mezzanotte il 25 dicembre 2015". Un tale orario locale non ha fuso orario. In effetti, non ha alcun significato reale fino a quando non lo modifichi in un determinato fuso orario. La mezzanotte del 25 arriva prima a Parigi che a Montréal. Pertanto, nelle app aziendali più comuni utilizziamo raramente "Local". Prenderete i vostri valori di data-ora memorizzati dal vostro database, lavorando con loro nella vostra logica di business in UTC in generale, e adeguandovi a un 'ZonedDateTime' solo per la presentazione a un utente. –

risposta

15

dipende da quale classe y ou uso:

  • Instant è un punto istantanea sulla linea di tempo globale (UTC), e non è correlato al fuso orario.
  • LocalDate e LocalDateTime non hanno alcun concetto di fuso orario, ma chiamando il numero now() ovviamente forniremo il vostro orario corretto.
  • OffsetDateTime ha un fuso orario, ma non supporta l'ora legale.
  • ZonedDateTime ha il supporto completo per il fuso orario.

Conversione tra di loro richiede di solito un fuso orario, in modo da rispondere alla tua domanda:

        Sì, Java 8 Data/ora può prendersi cura di ora legale, se si utilizza giusto

+0

grazie per aver detto che 'OffsetDateTime' non supporta l'ora legale, questo è esattamente ciò di cui avevo bisogno, grazie! –

3

Sì, l'API Java terrà conto delle modifiche all'ora legale.

Questo tutorial spiega abbastanza bene come convertire le date tra fusi orari e come scegliere la classe diritto di rappresentare una data: https://docs.oracle.com/javase/tutorial/datetime/iso/timezones.html

Si può anche guardare in questa classe che rappresenta le regole per ogni zona: http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html

in particolare, questo metodo può dire se un particolare istante è in ora legale: http://docs.oracle.com/javase/8/docs/api/java/time/zone/ZoneRules.html#isDaylightSavings-java.time.Instant-

+0

Grazie per aver ricordato il valore dei documenti Orcale :) Questi collegamenti sono più utili per me. – Raja

14

The Answer di Andreas è azzeccato.

Esempio Codice

Testiamo con un po 'di codice. DST in the United States & Il Canada scade quest'anno alle 02:00 del 1 novembre 2015.

Iniziamo con 1 AM in "locale" data-ora, ovvero non legato alla timeline e ignorando il problema dei fusi orari. Aggiungi un'ora e otteniamo 2 AM. Ha senso.

LocalDateTime localDateTime = LocalDateTime.of(2015 , Month.NOVEMBER , 1 , 1 , 0); // 1 AM anywhere. Not tied the timeline nor to any time zone. 
LocalDateTime localDateTimeOneHourLater = localDateTime.plusHours(1); // 2 AM anywhere, in no particular time zone, ignoring DST. 

Poi prendiamo specifica, con un determinato fuso orario.Prendiamo quell'una in qualsiasi luogo e la inseriamo nel fuso orario di America/Los_Angeles (costa occidentale degli Stati Uniti).

ZoneId zoneId_LosAngeles = ZoneId.of("America/Los_Angeles"); 
ZonedDateTime before = localDateTime.atZone(zoneId_LosAngeles); // Assign a time zone, tying this vague date-time idea/generality to an actual moment on the time line. 

Ora aggiungere un'ora e vedere cosa otteniamo. Se l'ora legale viene ignorata, otterremo 2 AM. Se l'ora legale viene rispettata, otterremo l'ora del mattino ... quando si raggiungono le 2 del mattino, lo wall-clock time torna indietro all'una ma con un nuovo offset rispetto all'ora UTC. Questo è colloquialmente noto come "fall back" in autunno (autunno).

ZonedDateTime after = before.plusHours(1); // 2 AM? Nope, 1 AM because DST Daylight Saving Time expires at 2 AM Nov 1, 2015. 

Discarica per consolle.

System.out.println("localDateTime : " + localDateTime); 
System.out.println("localDateTimeOneHourLater : " + localDateTimeOneHourLater); 
System.out.println("before : " + before); 
System.out.println("after : " + after); 

Quando eseguito, otteniamo questo risultato. Senza un fuso orario, 1 AM + 1 ora = 2 AM. Ricordare che questi sono valori di data e ora "locali", non UTC. Rappresentano solo la vaga idea di una data-ora, non un momento reale sulla timeline.

localDateTime : 2015-11-01T01:00 
localDateTimeOneHourLater : 2015-11-01T02:00 

Ma con fusi orari in vigore il giorno DST scade, si ottengono risultati diversi. Nota come l'ora del giorno rimane 01:00 ma il offset-from-UTC cambia da -07:00 a -08:00.

before : 2015-11-01T01:00-07:00[America/Los_Angeles] 
after : 2015-11-01T01:00-08:00[America/Los_Angeles] 

Forse questo sarebbe più chiaro e più facile da verificare se ci adattiamo in UTC. Possiamo farlo semplicemente accedendo agli oggetti before e after come oggetti Instant. Il System.out.println chiama quindi implicitamente il metodo toString.

System.out.println("before.toInstant : " + before.toInstant()); 
System.out.println("after.toInstant : " + after.toInstant()); 

Quando eseguito.

before.toInstant : 2015-11-01T08:00:00Z 
after.toInstant : 2015-11-01T09:00:00Z