Wyświetlaj wszystkie strefy czasowe z GMT i UTC w Javie

1. Przegląd

Zawsze, gdy mamy do czynienia z czasami i datami, potrzebujemy układu odniesienia. Standardem tego jest UTC, ale w niektórych aplikacjach widzimy również GMT.

Krótko mówiąc, UTC to standard, a GMT to strefa czasowa.

Oto, co mówi nam Wikipedia na temat tego, czego używać:

W większości przypadków czas UTC jest uważany za wymienny ze średnim czasem Greenwich (GMT), ale GMT nie jest już precyzyjnie definiowane przez społeczność naukową.

Innymi słowy, kiedy skompilujemy listę z przesunięciami stref czasowych w UTC, będziemy ją również mieli dla GMT.

Najpierw przyjrzymy się, jak to osiągnąć, w Javie 8, a następnie zobaczymy, jak możemy uzyskać ten sam wynik w Javie 7.

2. Pobieranie listy stref

Na początek musimy pobrać listę wszystkich zdefiniowanych stref czasowych.

W tym celu klasa ZoneId ma przydatną metodę statyczną:

Set availableZoneIds = ZoneId.getAvailableZoneIds();

Następnie możemy użyć zestawu do wygenerowania posortowanej listy stref czasowych wraz z odpowiadającymi im przesunięciami:

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()); }

Powyższa metoda wykorzystuje parametr enum , który reprezentuje przesunięcie, które chcemy zobaczyć:

public enum OffsetBase { GMT, UTC }

Przejdźmy teraz bardziej szczegółowo do kodu.

Po pobraniu wszystkich dostępnych identyfikatorów stref potrzebujemy rzeczywistego odniesienia do czasu, reprezentowanego przez LocalDateTime.now ().

Następnie używamy Java Stream API do iteracji po każdym wpisie w naszym zestawie identyfikatorów ciągów stref czasowych i przekształcania go w listę sformatowanych stref czasowych z odpowiednim przesunięciem.

Dla każdego z tych wpisów generujemy wystąpienie ZoneId z mapą (ZoneId :: of).

3. Pierwsze przesunięcia

Musimy również znaleźć rzeczywiste przesunięcia UTC. Na przykład w przypadku czasu środkowoeuropejskiego przesunięcie będzie wynosić +01: 00.

Aby uzyskać przesunięcie czasu UTC dla dowolnej strefy, możemy użyć metody getOffset () firmy LocalDateTime .

Należy również pamiętać, że Java reprezentuje +00: 00 przesunięć jak Z .

Tak więc, aby mieć spójną patrząc String dla stref czasowych z zerowego, będziemy zastępować Z z +00: 00:

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

4. Porównywanie stref

Opcjonalnie możemy również posortować strefy czasowe według przesunięcia.

W tym celu użyjemy klasy 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. Wyświetlanie stref czasowych

Wszystko, co pozostaje do zrobienia, to złożenie powyższych elementów razem, wywołując metodę getTimeZoneList () dla każdej wartości wyliczenia OffsetBase i wyświetlając listy:

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); } }

Kiedy uruchomimy powyższy kod, wydrukuje on strefy czasowe dla UTC i GMT.

Oto fragment tego, jak będzie wyglądać wynik:

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 i wcześniejsze

Java 8 ułatwia to zadanie, korzystając z interfejsów API Stream oraz Date and Time .

Jeśli jednak mamy Java 7 i przed projektem, nadal możemy osiągnąć ten sam rezultat, opierając się na klasie java.util.TimeZone z jej metodą 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; }

Główną różnicą w stosunku do kodu Java 8 jest obliczanie przesunięcia.

RawOffset otrzymujemy od TimeZone () „s getRawOffset () metoda wyraża czas zone offset w milisekundach .

Dlatego musimy przekonwertować to na godziny i minuty za pomocą klasy 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. Wnioski

W tym krótkim samouczku widzieliśmy, jak możemy skompilować listę wszystkich dostępnych stref czasowych z ich przesunięciami UTC i GMT.

Jak zawsze, pełny kod źródłowy przykładów jest dostępny na GitHub.