2014-11-12 6 views
6

Uso la nuova implementazione java.time di Java 8, una meraviglia sull'output di un risultato di conversione dell'ora da UTC a CET.java.time: il fuso orario CET considera l'ora legale?

ZonedDateTime utcTime = ZonedDateTime.of(2014, 7, 1, 8, 0, 0, 0, ZoneId.of("UTC")); 
ZonedDateTime cetTime = ZonedDateTime.ofInstant(utcTime.toInstant(), ZoneId.of("CET")); 
System.out.println("Summer-UTC-Time: " + utcTime); 
System.out.println("Summer-CET-Time: " + cetTime); 

System.out.println(); 

utcTime = ZonedDateTime.of(2014, 1, 1, 8, 0, 0, 0, ZoneId.of("UTC")); 
cetTime = ZonedDateTime.ofInstant(utcTime.toInstant(), ZoneId.of("CET")); 
System.out.println("Winter-UTC-Time: " + utcTime); 
System.out.println("Winter-CET-Time: " + cetTime); 

mi aspettavo che il tempo CET sarebbe sempre uno del tempo UTC, ma invece ho ottenuto:

Summer-UTC-Time: 2014-07-01T08:00Z[UTC] 
Summer-CET-Time: 2014-07-01T10:00+02:00[CET] -> +2 **Unexpected** 

Winter-UTC-Time: 2014-01-01T08:00Z[UTC] 
Winter-CET-Time: 2014-01-01T09:00+01:00[CET] -> +1 Expected 

Quindi a quanto pare ho a che fare con l'ora legale, che non mi aspettavo quando usando CET. È il java.time CET in verità CEST? E se sì, quale zona dovrei usare se ho bisogno del CET?

+0

'CET' non è identico a' UTC + 1', almeno, come il database dei fusi orari IANA lo definisce. E questo è ciò che usano Java, POSIX e diversi fornitori di database. – Holger

+0

@Holger Il tuo commento "CET non è identico a UTC + 1" sembra essere la risposta più corretta - sebbene il riferimento [wiki] (http://en.wikipedia.org/wiki/Central_European_Time) documenti un offset UTC fisso di +1 (+2 sarebbe CEST nelle regioni con DST). Ho dato una rapida occhiata a IANA ma questo non mi ha aiutato a capire la loro definizione. Tuttavia se aggiungete il vostro commento come risposta (magari fornendo qualche informazione di più) lo accetterei. – FrVaBe

risposta

10

Il IANA definition of CET è che segue le regole del fuso orario dell'Europa centrale, che comprende sia l'inverno che l'ora legale. Le regole possono essere viste here, che mostra che "CET" è basato su "C-Eur" che include l'ora legale.

In java.time si può anche vedere il set completo di regole:

ZoneId zone = ZoneId.of("CET"); 
System.out.println(zone); 
System.out.println(zone.getRules()); 
for (ZoneOffsetTransition trans : zone.getRules().getTransitions()) { 
    System.out.println(trans); 
} 
for (ZoneOffsetTransitionRule rule : zone.getRules().getTransitionRules()) { 
    System.out.println(rule); 
} 

che stampa:

CET 
ZoneRules[currentStandardOffset=+01:00] 
Transition[Gap at 1916-04-30T23:00+01:00 to +02:00] 
Transition[Overlap at 1916-10-01T01:00+02:00 to +01:00] 
Transition[Gap at 1917-04-16T02:00+01:00 to +02:00] 
Transition[Overlap at 1917-09-17T03:00+02:00 to +01:00] 
Transition[Gap at 1918-04-15T02:00+01:00 to +02:00] 
Transition[Overlap at 1918-09-16T03:00+02:00 to +01:00] 
Transition[Gap at 1940-04-01T02:00+01:00 to +02:00] 
Transition[Overlap at 1942-11-02T03:00+02:00 to +01:00] 
Transition[Gap at 1943-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1943-10-04T03:00+02:00 to +01:00] 
Transition[Gap at 1944-04-03T02:00+01:00 to +02:00] 
Transition[Overlap at 1944-10-02T03:00+02:00 to +01:00] 
Transition[Gap at 1945-04-02T02:00+01:00 to +02:00] 
Transition[Overlap at 1945-09-16T03:00+02:00 to +01:00] 
Transition[Gap at 1977-04-03T02:00+01:00 to +02:00] 
Transition[Overlap at 1977-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1978-04-02T02:00+01:00 to +02:00] 
Transition[Overlap at 1978-10-01T03:00+02:00 to +01:00] 
Transition[Gap at 1979-04-01T02:00+01:00 to +02:00] 
Transition[Overlap at 1979-09-30T03:00+02:00 to +01:00] 
Transition[Gap at 1980-04-06T02:00+01:00 to +02:00] 
Transition[Overlap at 1980-09-28T03:00+02:00 to +01:00] 
Transition[Gap at 1981-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1981-09-27T03:00+02:00 to +01:00] 
Transition[Gap at 1982-03-28T02:00+01:00 to +02:00] 
Transition[Overlap at 1982-09-26T03:00+02:00 to +01:00] 
Transition[Gap at 1983-03-27T02:00+01:00 to +02:00] 
Transition[Overlap at 1983-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1984-03-25T02:00+01:00 to +02:00] 
Transition[Overlap at 1984-09-30T03:00+02:00 to +01:00] 
Transition[Gap at 1985-03-31T02:00+01:00 to +02:00] 
Transition[Overlap at 1985-09-29T03:00+02:00 to +01:00] 
Transition[Gap at 1986-03-30T02:00+01:00 to +02:00] 
Transition[Overlap at 1986-09-28T03:00+02:00 to +01:00] 
Transition[Gap at 1987-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1987-09-27T03:00+02:00 to +01:00] 
Transition[Gap at 1988-03-27T02:00+01:00 to +02:00] 
Transition[Overlap at 1988-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1989-03-26T02:00+01:00 to +02:00] 
Transition[Overlap at 1989-09-24T03:00+02:00 to +01:00] 
Transition[Gap at 1990-03-25T02:00+01:00 to +02:00] 
Transition[Overlap at 1990-09-30T03:00+02:00 to +01:00] 
Transition[Gap at 1991-03-31T02:00+01:00 to +02:00] 
Transition[Overlap at 1991-09-29T03:00+02:00 to +01:00] 
Transition[Gap at 1992-03-29T02:00+01:00 to +02:00] 
Transition[Overlap at 1992-09-27T03:00+02:00 to +01:00] 
Transition[Gap at 1993-03-28T02:00+01:00 to +02:00] 
Transition[Overlap at 1993-09-26T03:00+02:00 to +01:00] 
Transition[Gap at 1994-03-27T02:00+01:00 to +02:00] 
Transition[Overlap at 1994-09-25T03:00+02:00 to +01:00] 
Transition[Gap at 1995-03-26T02:00+01:00 to +02:00] 
Transition[Overlap at 1995-09-24T03:00+02:00 to +01:00] 
Transition[Gap at 1996-03-31T02:00+01:00 to +02:00] 
Transition[Overlap at 1996-10-27T03:00+02:00 to +01:00] 
Transition[Gap at 1997-03-30T02:00+01:00 to +02:00] 
Transition[Overlap at 1997-10-26T03:00+02:00 to +01:00] 
TransitionRule[Gap +01:00 to +02:00, SUNDAY on or after MARCH 25 at 02:00 STANDARD, standard offset +01:00] 
TransitionRule[Overlap +02:00 to +01:00, SUNDAY on or after OCTOBER 25 at 02:00 STANDARD, standard offset +01:00] 

La chiave qui è quello di capire che l'identificatore fuso orario e la "short name" di che identificatore sono due diversi elementi. L'identificatore è sempre fissato come "CET", ma il nome cambia tra "CET" e "CEST".

+0

Ancora confuso per me che è in qualche modo diverso dalla solita spiegazione di CET che può essere trovata al di fuori di IANA (ad esempio wikipedia) ma sicuramente la migliore - e corretta - risposta. Grazie. – FrVaBe

1

Poiché si conosce l'offset e non si desidera utilizzare DTS, perché non utilizzare il metodo ZoneOffset.ofHours(1) anziché ZoneId.of("CET")?

Inoltre, è possibile chiamare normalized() in qualsiasi istanza ZoneId per impostarlo come offset fisso ma suona meno affidabile rispetto all'utilizzo di un offset dall'inizio.

Da ZoneId javadoc:

Un IDArea viene utilizzato per identificare le regole utilizzate per la conversione tra un istantaneo e un LocalDateTime. Ci sono due tipi distinti di ID:

  • offset fissi - un risolta completamente compensati da UTC/Greenwich, che utilizza lo stesso offset per tutti i data-ora locale
  • regioni geografiche - una zona in cui un insieme specifico di si applicano le regole per trovare l'offset da UTC/Greenwich

La maggior parte degli offset fissi sono rappresentati da ZoneOffset. La chiamata normalizzata() su qualsiasi ZoneId garantirà che un ID offset fisso verrà rappresentato comecome ZoneOffset.

Se non si utilizzano offset fissi, quindi si utilizzano le regioni geografiche che significa che dipende dalla regione se DTS è osservato o meno. Lo stesso vale per PST. Vedrai che osserva DTS anche se l'ora legale è chiamata PDT. Sì, è confuso, ma è così che funziona la maggior parte degli strumenti. Leggi l'intero ZoneId javadoc per una spiegazione più approfondita (la sezione Time-zone IDs).

+0

Ho bisogno di leggere un valore di data da un database che considero essere in CET. Ho pensato di utilizzare il TimeZone e le regole corrispondenti gestivano gli offset e l'ora legale (se pertinente) per me. – FrVaBe

+0

@FrVaBe, dovrebbe gestirlo. Leggi http://www.timeanddate.com/time/zones/cet. Vedrai che la zona copre le regioni che fanno l'osservatore DTS. Ci sono regioni con lo stesso fuso orario ma senza DTS che sono scritte come +1. Pensi che il sistema che memorizza i valori in DB stia usando CET per aree che sono in realtà +1? btw questo è uno dei motivi per memorizzare sempre UTC in DB. L'altro è che a volte l'ora locale con DTS non può essere convertita in modo univoco in UTC. – akostadinov

+0

Ho solo pensato - come indicato nel link che hai fornito - CET è sempre UTC + 1 - altrimenti sarebbe CEST. In questo caso il CET sarà buono quanto l'UTC. La conversione tra entrambi sarebbe semplice, ma ora osservo che l'ora legale è importante in CET e mi chiedo perché. La mia semplice domanda potrebbe essere: Perché CET non è sempre UTC + 1 quando si utilizza java.time? – FrVaBe