Visualizza tutti i fusi orari con GMT e UTC in Java

1. Panoramica

Ogni volta che abbiamo a che fare con orari e date, abbiamo bisogno di un quadro di riferimento. Lo standard per questo è UTC, ma in alcune applicazioni vediamo anche GMT.

In breve, UTC è lo standard, mentre GMT è un fuso orario.

Questo è ciò che Wikipedia ci dice riguardo a cosa usare:

Per la maggior parte degli scopi, l'UTC è considerato intercambiabile con il Greenwich Mean Time (GMT), ma il GMT non è più definito con precisione dalla comunità scientifica.

In altre parole, una volta compilato un elenco con offset di fuso orario in UTC, lo avremo anche per GMT.

Per prima cosa, daremo un'occhiata al modo in cui Java 8 è possibile ottenere questo risultato e poi vedremo come possiamo ottenere lo stesso risultato in Java 7.

2. Ottenere un elenco di zone

Per cominciare, dobbiamo recuperare un elenco di tutti i fusi orari definiti.

A tal fine, la classe ZoneId ha un pratico metodo statico:

Set availableZoneIds = ZoneId.getAvailableZoneIds();

Quindi, possiamo usare il Set per generare un elenco ordinato di fusi orari con i rispettivi offset:

public List getTimeZoneList(OffsetBase base) { LocalDateTime now = LocalDateTime.now(); return ZoneId.getAvailableZoneIds().stream() .map(ZoneId::of) .sorted(new ZoneComparator()) .map(id -> String.format( "(%s%s) %s", base, getOffset(now, id), id.getId())) .collect(Collectors.toList()); }

Il metodo sopra usa un parametro enum che rappresenta l'offset che vogliamo vedere:

public enum OffsetBase { GMT, UTC }

Ora esaminiamo il codice in modo più dettagliato.

Dopo aver recuperato tutti gli ID di zona disponibili, abbiamo bisogno di un riferimento temporale effettivo, rappresentato da LocalDateTime.now ().

Dopodiché, utilizziamo l' API Stream di Java per iterare su ciascuna voce nel nostro set di ID stringa del fuso orario e trasformarla in un elenco di fusi orari formattati con l'offset corrispondente.

Per ognuna di queste voci, generiamo un'istanza ZoneId con map (ZoneId :: of).

3. Ottenere offset

Dobbiamo anche trovare gli offset UTC effettivi. Ad esempio, nel caso dell'ora dell'Europa centrale, l'offset sarebbe +01: 00.

Per ottenere l'offset UTC per una data zona, possiamo usare il metodo getOffset () di LocalDateTime .

Si noti inoltre che Java rappresenta +00: 00 offset come Z .

Quindi, per avere una stringa dall'aspetto coerente per i fusi orari con offset zero, sostituiremo Z con +00: 00:

private String getOffset(LocalDateTime dateTime, ZoneId id) { return dateTime .atZone(id) .getOffset() .getId() .replace("Z", "+00:00"); }

4. Rendere le zone comparabili

Facoltativamente, possiamo anche ordinare i fusi orari in base all'offset.

Per questo, useremo una classe ZoneComparator :

private class ZoneComparator implements Comparator { @Override public int compare(ZoneId zoneId1, ZoneId zoneId2) { LocalDateTime now = LocalDateTime.now(); ZoneOffset offset1 = now.atZone(zoneId1).getOffset(); ZoneOffset offset2 = now.atZone(zoneId2).getOffset(); return offset1.compareTo(offset2); } }

5. Visualizzazione dei fusi orari

Tutto ciò che resta da fare è mettere insieme i pezzi precedenti chiamando il metodo getTimeZoneList () per ogni valore di enumerazione OffsetBase e visualizzando gli elenchi:

public class TimezoneDisplayApp { public static void main(String... args) { TimezoneDisplay display = new TimezoneDisplay(); System.out.println("Time zones in UTC:"); List utc = display.getTimeZoneList( TimezoneDisplay.OffsetBase.UTC); utc.forEach(System.out::println); System.out.println("Time zones in GMT:"); List gmt = display.getTimeZoneList( TimezoneDisplay.OffsetBase.GMT); gmt.forEach(System.out::println); } }

Quando eseguiamo il codice sopra, stamperà i fusi orari per UTC e GMT.

Ecco uno snippet di come apparirà l'output:

Time zones in UTC: (UTC+14:00) Pacific/Apia (UTC+14:00) Pacific/Kiritimati (UTC+14:00) Pacific/Tongatapu (UTC+14:00) Etc/GMT-14

6. Java 7 e versioni precedenti

Java 8 semplifica questa attività utilizzando le API Stream e Data e ora .

Tuttavia, se abbiamo Java 7 e prima di un progetto, possiamo comunque ottenere lo stesso risultato affidandoci alla classe java.util.TimeZone con il suo metodo getAvailableIDs () :

public List getTimeZoneList(OffsetBase base) { String[] availableZoneIds = TimeZone.getAvailableIDs(); List result = new ArrayList(availableZoneIds.length); for (String zoneId : availableZoneIds) { TimeZone curTimeZone = TimeZone.getTimeZone(zoneId); String offset = calculateOffset(curTimeZone.getRawOffset()); result.add(String.format("(%s%s) %s", base, offset, zoneId)); } Collections.sort(result); return result; }

La differenza principale con il codice Java 8 è il calcolo dell'offset.

Il rawOffset che otteniamo da fuso orario () 's getRawOffset () metodo esprime l'offset in millisecondi orario del tempo .

Pertanto, dobbiamo convertirlo in ore e minuti utilizzando la classe TimeUnit :

private String calculateOffset(int rawOffset) { if (rawOffset == 0) { return "+00:00"; } long hours = TimeUnit.MILLISECONDS.toHours(rawOffset); long minutes = TimeUnit.MILLISECONDS.toMinutes(rawOffset); minutes = Math.abs(minutes - TimeUnit.HOURS.toMinutes(hours)); return String.format("%+03d:%02d", hours, Math.abs(minutes)); }

7. Conclusione

In questo rapido tutorial, abbiamo visto come possiamo compilare un elenco di tutti i fusi orari disponibili con i rispettivi offset UTC e GMT.

E, come sempre, il codice sorgente completo per gli esempi è disponibile su GitHub.