2012-11-02 15 views
18

Sto cercando di ottenere una conversione semplice da un fuso orario in un altro utilizzando Data e Calendario Java. Sto cercando di eseguire il seguente codiceConverti data in fuso orario diverso

Calendar instance = Calendar.getInstance(TimeZone.getTimeZone("Europe/London")); 
    Date date = instance.getTime(); 
    System.out.println(date); 

    GregorianCalendar instance2 = new GregorianCalendar(TimeZone.getTimeZone("Europe/Athens")); 
    instance2.setTime(instance.getTime()); 
    System.out.println(instance2.getTime()); 

ma che ancora restituisce la stessa data, piuttosto che uno ora ... L'intero problema sembra banale, ma non riesco a trovare una risposta semplice a questa. Grazie in anticipo per il vostro aiuto.

+4

Ti piacerebbe utilizzare [Joda time] (http://stackoverflow.com/a/37580/3/1037210)? È la mia preferenza – Lion

+0

Controlla [questa risposta] (http://stackoverflow.com/questions/230126/how-to-handle-calendar-timezones-using-java). Potrebbe tornare utile. – Gamb

+0

Ho trovato un'altra cosa sul web, che è probabilmente la soluzione più pulita, per utilizzare un formato di data e ora per analizzare la stringa della data e restituire la data nel fuso orario corrispondente – Bober02

risposta

31

Quando si stampa la data utilizzando System.out.println(date); or System.out.println(instance2.getTime());, il Date restituito da instance2.getTime() è TimeZone independent e sempre stampa la data nel fuso orario locale.

Invece si consiglia di utilizzare DateFormat/SimpleDateFormat:

DateFormat formatter= new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z"); 
    formatter.setTimeZone(TimeZone.getTimeZone("Europe/London")); 
    System.out.println(formatter.format(date)); 

    formatter.setTimeZone(TimeZone.getTimeZone("Europe/Athens")); 
    System.out.println(formatter.format(instance2.getTime())) 
+0

Sei sicuro che sia il fuso orario locale e non i secondi EPOCH (indipendente dal fuso orario)? http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTime() – akaIDIOT

+0

@akaIDIOT la rappresentazione interna è fin dall'epoca, quando viene stampata la data viene utilizzato il fuso orario locale , una funzionalità/bug di 'java.util.Date'. – dan

+0

@ Bober02: hai trovato qualcosa di meglio? Se sì, per favore condividi. –

2

È possibile utilizzare il seguente frammento di codice

String dateString = "14 Jul 2014 00:11:04 CEST"; 
date = formatter.parse(dateString); 
System.out.println(formatter.format(date)); 

// Set the formatter to use a different timezone - Indochina Time 
formatter.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok")); 
System.out.println("ICT time : "+formatter.format(date)); 
8

La risposta accettata è corretta. La classe java.util.Date non ha un fuso orario assegnato a , tuttavia l'implementazione di toString applica in modo confuso il fuso orario predefinito corrente della JVM.

Evitare java.util.Date & .Calendar

Questo è uno dei tanti motivi per evitare il java.util.Date notoriamente problematico, .Calendar, e le classi SimpleDateFormat bundle con Java. Evitalo. Invece utilizzare:

Joda Time

qualche esempio di codice in Joda-Time 2.3 segue. Cerca StackOveflow per molti altri esempi e molte discussioni.

DateTimeZone timeZoneLondon = DateTimeZone.forID("Europe/London"); 
DateTimeZone timeZoneAthens = DateTimeZone.forID("Europe/Athens"); 

DateTime nowLondon = DateTime.now(timeZoneLondon); 
DateTime nowAthens = nowLondon.withZone(timeZoneAthens); 
DateTime nowUtc = nowLondon.withZone(DateTimeZone.UTC); 

java.time ha

Java 8 e versioni successive di un nuovo java.time package built-in. Questo pacchetto è stato ispirato da Joda-Time. Mentre condividono alcune somiglianze e nomi di classe, sono diversi; ognuno ha caratteristiche le altre mancanze. Una differenza notevole è che java.time evita i costruttori, invece utilizza metodi di istanziazione statici.

Nel caso di questa domanda, funzionano allo stesso modo. Specificare un fuso orario e chiamare un metodo now per ottenere il momento corrente, quindi creare una nuova istanza basata sulla vecchia istanza immutabile da regolare per il fuso orario.

Annotare le due diverse classi di fuso orario. Uno è un fuso orario con nome che include tutte le regole per l'ora legale e altre anomalie di questo tipo più uno scostamento da UTC mentre l'altro è solo l'offset.

ZoneId zoneMontréal = ZoneId.of("America/Montreal"); 
ZonedDateTime nowMontréal = ZonedDateTime.now (zoneMontréal); 

ZoneId zoneTokyo = ZoneId.of("Asia/Tokyo"); 
ZonedDateTime nowTokyo = nowMontréal.withZoneSameInstant(zoneTokyo); 

ZonedDateTime nowUtc = nowMontréal.withZoneSameInstant(ZoneOffset.UTC); 

realtà la classe java.util.Date fa hanno un fuso sepolta all'interno its source code. Ma la classe ignora quel fuso orario per la maggior parte degli scopi pratici. Quindi, come abbreviazione, si dice spesso che j.u.Date non ha un fuso orario assegnato. Confondere? Sì. Evita il casino che è j.u.Date e vai con Joda-Time e/o java.time.

Problemi correlati