2015-03-19 15 views

risposta

32

Aggiornato per amore della correzione:

Nella maggior parte dei casi sì lo stesso, vedere l'esempio seguente per il Brasile quando si passa da inverno a estate:

ZonedDateTime zdt = 
    ZonedDateTime.of(2015, 10, 18, 0, 30, 0, 0, 
    ZoneId.of("America/Sao_Paulo")); // switch to summer time 
ZonedDateTime zdt1 = zdt.truncatedTo(ChronoUnit.DAYS); 
ZonedDateTime zdt2 = zdt.toLocalDate().atStartOfDay(zdt.getZone()); 

System.out.println(zdt); // 2015-10-18T01:30-02:00[America/Sao_Paulo] 
System.out.println(zdt1); // 2015-10-18T01:00-02:00[America/Sao_Paulo] 
System.out.println(zdt2); // 2015-10-18T01:00-02:00[America/Sao_Paulo] 

troncamento accade sulla timeline locale. Se scegli GIORNI, opti per mezzanotte. Secondo javadoc il metodo truncate() converte infine nel nuovo ZonedDateTime e sposta l'ora in avanti della dimensione del divario (1 ora).

Convertire la zdt prima a LocalDate (tagliando la parte relativa all'ora) e quindi cercando il suo ZonedDateTime -part in un determinato fuso orario è effettivamente la stessa per questa situazione.

Tuttavia, per il retro del ritorno dall'ora legale all'ora invernale c'è un'eccezione (grazie mille a @Austin che ha fornito un esempio di contatore). Il problema è durante la sovrapposizione quando decidere quale offset utilizzare. Di solito la classe ZonedDateTime è stato progettato/specificato di utilizzare compensare la precedente, si veda anche questo estratto da Javadoc:

per le sovrapposizioni, la strategia generale è che se il locale di data-ora cade nel bel mezzo di una sovrapposizione, quindi l'offset precedente sarà mantenuto. Se non esiste uno spostamento precedente o l'offset precedente è non valido, viene utilizzato lo scostamento precedente, in genere il tempo "estivo".

Se la classe ZonedDateTime avrebbe di conseguenza seguire la propria specifica poi entrambe le procedure sarebbero ancora significato equivalente:

zdt.truncatedTo(ChronoUnit.DAYS); 

dovrebbe essere equivalente a

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withEarlierOffsetAtOverlap(); 

Ma il reale comportamento in base alla esempio di @Austin e confermato da me nel proprio test è:

zdt.toLocalDate().atStartOfDay().atZone(zdt.getZone()).withLaterOffsetAtOverlap(); 

Sembra un'inconsistenza nascosta nella classe ZonedDateTime, leggermente parlata. Se mi chiedi quale metodo preferire, preferirei piuttosto il secondo metodo, anche se è molto più lungo e richiede più sequenze di tasti. Ma ha il grande vantaggio di essere più trasparente su ciò che fa. Un altro motivo per preferire il secondo approccio è:

Ottiene davvero il PRIMO istante in cui l'ora locale è uguale all'inizio del giorno. Altrimenti, quando si utilizza il primo metodo, è necessario scrivere:

zdt.truncatedTo(ChronoUnit.DAYS).withEarlierOffsetAtOverlap(); 
+0

Questo non è sempre corretto! Vedi la mia risposta per perché no. – Austin

+0

@ Austin La tua risposta sembra essere plausibile. Indagherò e correggerò la mia risposta di conseguenza. –

21

Sono leggermente diversi.Secondo il javadocs, truncatedTo() proverà a conservare il fuso orario in caso di sovrapposizione, ma atStartOfDay() troverà la prima occorrenza di mezzanotte.

Ad esempio, Cuba ripristina l'ora legale alle 1:00, rientrando alle 12:00. Se si inizia con un intervallo di tempo successivo a tale transizione, atStartOfDay() restituirà la prima occorrenza delle 12, mentre truncatedTo() restituirà la seconda occorrenza.

ZonedDateTime zdt = ZonedDateTime.of(2016, 11, 6, 2, 0, 0, 0, ZoneId.of("America/Havana")); 
ZonedDateTime zdt1 = zdt.truncatedTo(ChronoUnit.DAYS); 
ZonedDateTime zdt2 = zdt.toLocalDate().atStartOfDay(zdt.getZone()); 

System.out.println(zdt); // 2016-11-06T02:00-05:00[America/Havana] 
System.out.println(zdt1); // 2016-11-06T00:00-05:00[America/Havana] 
System.out.println(zdt2); // 2016-11-06T00:00-04:00[America/Havana] 
+1

Grazie mille per aver trovato un contro-esempio. Ti ho sviato e anche aggiornato la mia risposta. –

0

Nota c'è anche un altro modo di farlo:

zonedDateTime.with(LocalTime.MIN); 

che produce lo stesso risultato di truncatedTo

+0

Questa non è davvero una risposta. – shmosel

Problemi correlati