2013-04-03 21 views
6

Come si ottiene la differenza di fuso orario da GMT per una data e un fuso orario specifici in Java?Java: calcolo della differenza di fuso orario

Determinare se un fuso orario specifico è in ora legale è abbastanza straight-forward:

boolean isIsraelInDST = TimeZone.getTimeZone("Israel").inDaylightTime(new Date()); 

Come faccio ad avere la differenza di tempo reale?

+0

FYI, le fastidiose vecchie classi data-ora come "TimeZone', [' java.util.Date'] (https://docs.oracle.com/javase/9/docs/api/java/util/ Date.html), ['java.util.Calendar'] (https://docs.oracle.com/javase/9/docs/api/java/util/Calendar.html) e' java.text.SimpleDateFormat' sono ora [legacy] (https://en.wikipedia.org/wiki/Legacy_system), soppiantati dal [java.time] (https://docs.oracle.com/javase/9/docs/api/java/ time/package-summary.html) classi integrate in Java 8 e Java 9. Vedi [* Tutorial * di Oracle] (https://docs.oracle.com/javase/tutorial/datetime/TOC.html). –

risposta

14

Usa TimeZone.getRawOffset(): Restituisce la quantità di tempo in millisecondi da aggiungere a UTC per ottenere l'ora standard in questo fuso orario. Poiché questo valore non è influenzato dall'ora legale, viene chiamato offset raw.

Se si desidera che l'offset includa l'ora legale, si utilizza TimeZone.getOffset (data lunga). Si dovrebbe fornire la data concreta al metodo, ad esempio ora - System.currentTimeMillis()

+0

Voglio l'offset * incluso * DST. –

+0

Mi dispiace di pubblicare su un thread così vecchio ma ho una confusione. Se utilizzo TimeZone.getOffset (data lunga) presuppone che il parametro data sia in ora locale o UTC? Specificamente se lo chiami con una data che è poche ore prima di un giorno in cui l'ora del risparmio di luce passa a New York ma poche ore dopo in UTC includerà l'interruttore o no? –

+0

long date is milliseconds dal 1970-01-01 UTC. –

7

Vedo che questo è un thread vecchio, ma aggiungendo questo poiché recentemente ho avuto un requisito simile - Questo dà la differenza effettiva in millis basato sull'ora ATTUALE (millisecondi di epoca).

TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis()) 
7

suggerisco di aggiungere il periodo estivo/invernale offset getRawOffset:

TimeZone tz1 = TimeZone.getTimeZone("GMT"); 
    TimeZone tz2 = TimeZone.getTimeZone("America/New_York"); 
    long timeDifference = tz1.getRawOffset() - tz2.getRawOffset() + tz1.getDSTSavings() - tz2.getDSTSavings(); 
2
public String timeZone(Date date) { 
    TimeZone timeZone = TimeZone.getTimeZone("America/New_York"); 
    long millis = timeZone.getRawOffset() + (timeZone.inDaylightTime(date) ? timeZone.getDSTSavings() : 0); 

    return String.format("%s%s:%s", 
      millis < 0 ? "-" : "+", 
      String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toHours(millis))), 
      String.format("%02d", Math.abs(TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)))) 
    ); 
} 
0

tl; dr

ZoneId.of("Pacific/Auckland") // Specify a time zone. 
    .getRules()     // Get the object representing the rules for all the past, present, and future changes in offset used by the people in the region of that zone. 
    .getOffset(Instant.now()) // Get a `ZoneOffset` object representing the number of hours, minutes, and seconds displaced from UTC. Here we ask for the offset in effect right now. 
    .toString()     // Generate a String in standard ISO 8601 format. 

+13: 00

Per il primo momento di una certa data.

ZoneId.of("Pacific/Auckland") 
    .getRules() 
    .getOffset( 
     LocalDate.of(2018 , Month.AUGUST , 23)   // Specify a certain date. Has no concept of time zone or offset. 
     .atStartOfDay(ZoneId.of("Pacific/Auckland")) // Determine the first moment of the day on that date in that region. Not always `00:00:00` because of anomalies such as Daylight Saving Time. 
     .toInstant()          // Adjust to UTC by extracting an `Instant`. 
    ) 
    .toString() 

+12: 00

Evitare legacy classi data-ora

Le altre risposte sono antiquati, come la classe TimeZone è ora eredità. Questa e altre classi fastidiose di data e ora sono soppiantate dalle classi temporali java.time.

java.time

Ora usiamo ZoneId, ZoneOffset, e ZoneRules invece che l'eredità TimeZone di classe.

Specificare un proper time zone name nel formato continent/region, come ad esempio America/Montreal, Africa/Casablanca o Pacific/Auckland. Non utilizzare mai l'abbreviazione di 3-4 lettere come EST o IST poiché sono non fusi orari reali, non standardizzati e nemmeno univoci (!).

ZoneId z = ZoneId.of("Africa/Tunis") ; 

Scarica le regole per quella zona.

ZoneRules rules = z.getRules() ; 

Chiedi le regole, se l'ora legale (DST) è a tutti gli effetti in un certo momento. Specifica il momento come Instant. La classe Instant rappresenta un momento nella timeline in UTC con una risoluzione di nanoseconds (fino a nove (9) cifre di una frazione decimale).

Instant instant = Instant.now() ; // Capture current moment in UTC. 
boolean isDst = rules.isDaylightSavings(instant) ; 

Come posso ottenere la differenza di tempo reale?

Non sei sicuro di quello che vuoi dire, ma io vi immagino si sta chiedendo l'offset-from-UTC in vigore in quel momento per il rispetto della zona. Un offset è un numero di ore, minuti e secondi di spostamento da UTC. Rappresentiamo un offset utilizzando la classe ZoneOffset. Un fuso orario è una cronologia delle modifiche passate, presenti e future in offset utilizzate dalle persone di una particolare regione. Rappresentiamo un fuso orario utilizzando la classe ZoneId.

Poiché l'offset può variare nel tempo per una regione, è necessario passare un momento quando si richiede un offset.

ZoneOffset offset = rules.getOffset(instant) ; 

generare una stringa che rappresenta che compensato in ISO 8601 formato standard.

String output output = offset.toString() ; 

È possibile chiedere l'offset come numero totale di secondi.

int offsetInSeconds = offset.getTotalSeconds() ; 

Chi java.time

Il quadro java.time è costruito in Java 8 e versioni successive. Queste classi soppiantano le fastidiose classi di data legacy come java.util.Date, Calendar, & SimpleDateFormat.

Il progetto Joda-Time, ora in maintenance mode, consiglia la migrazione alle classi java.time.

Per ulteriori informazioni, vedere Oracle Tutorial. E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310.

Utilizzando un JDBC driver compatibile con JDBC 4.2 o poi, si può scambiare java.time oggetti direttamente con il database. Nessuna necessità di stringhe o classi java.sql. *.

Dove ottenere le classi java.time?

  • Java SE 8, Java SE 9, e più tardi
    • incorporato.
    • Parte dell'API Java standard con un'implementazione in bundle.
    • Java 9 aggiunge alcune funzionalità e correzioni minori.
  • Java SE 6 e Java SE 7
    • Molte delle funzionalità java.time è di back-porting per Java 6 .
  • Android
    • versioni successive di implementazioni fascio Android delle classi java.time.
    • Per Android precedente, il progetto ThreeTenABP si adatta a ThreeTen-Backport (menzionato sopra). Vedi How to use ThreeTenABP….

Il progetto ThreeTen-Extra java.time prolunga con classi aggiuntive. Questo progetto è un terreno di prova per possibili aggiunte future a java.time. È possibile trovare alcune classi utili come Interval, YearWeek, YearQuarter e more.