Показване на всички часови зони с GMT и UTC в Java

1. Общ преглед

Винаги, когато се занимаваме с часове и дати, се нуждаем от референтна рамка. Стандартът за това е UTC, но в някои приложения виждаме и GMT.

Накратко, UTC е стандарт, докато GMT е часова зона.

Ето какво ни казва Уикипедия относно това какво да използваме:

За повечето цели UTC се счита за взаимозаменяем със средното време по Гринуич (GMT), но GMT вече не е точно дефиниран от научната общност.

С други думи, след като съставим списък с отмествания на часовата зона в UTC, ще го имаме и за GMT.

Първо ще разгледаме начина на постигане на Java 8 и след това ще видим как можем да получим същия резултат в Java 7.

2. Получаване на списък със зони

Като начало трябва да извлечем списък с всички дефинирани часови зони.

За тази цел класът ZoneId има удобен статичен метод:

Set availableZoneIds = ZoneId.getAvailableZoneIds();

След това можем да използваме Set, за да генерираме сортиран списък с часови зони със съответните им отмествания:

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

Горният метод използва enum параметър, който представлява изместването, което искаме да видим:

public enum OffsetBase { GMT, UTC }

Сега нека да разгледаме кода по-подробно.

След като извлечем всички налични идентификатори на зони, се нуждаем от реална справка за времето, представена от LocalDateTime.now ().

След това използваме Java Stream API, за да итерираме всеки запис в набора ни от низове на низове за часова зона и да го трансформираме в списък с форматирани часови зони със съответното отместване.

За всеки от тези записи генерираме екземпляр ZoneId с map (ZoneId :: of).

3. Получаване на компенсации

Също така трябва да намерим действителни отмествания по UTC. Например, в случай на централноевропейско време, изместването ще бъде +01: 00.

За да получим UTC отместването за всяка дадена зона, можем да използваме метода getOffset () на LocalDateTime .

Също така имайте предвид, че Java представлява +00: 00 компенсации като Z .

Така че, за да имаме последователно изглеждащ низ за часови зони с нулево отместване, ще заменим Z с +00: 00:

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

4. Осигуряване на сравними зони

По желание можем да сортираме и часовите зони според отместването.

За това ще използваме клас 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. Показване на часови зони

Остава само да се съберат горните парчета, като се извика методът getTimeZoneList () за всяка стойност на изброяване на OffsetBase и се покажат списъците:

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

Когато стартираме горния код, той ще отпечата часовите зони за UTC и GMT.

Ето фрагмент за това как ще изглежда изходът:

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 и преди

Java 8 улеснява тази задача, като използва API за поток и дата и час .

Ако обаче имаме Java 7 и преди проект, все пак можем да постигнем същия резултат, като разчитаме на класа java.util.TimeZone с метода 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; }

Основната разлика с кода на Java 8 е изчислението на отместването.

В rawOffset , която получаваме от TimeZone () е getRawOffset () метод изразява часовия пояс-те компенсират за части от секундата .

Следователно трябва да преобразуваме това в часове и минути с помощта на класа 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. Заключение

В този бърз урок видяхме как можем да съставим списък на всички налични часови зони с техните отмествания UTC и GMT.

И както винаги, пълният изходен код за примерите е достъпен в GitHub.