Рубрики
Без рубрики

Отображение Всех Часовых Поясов С GMT И UTC на Java

Взгляните на отображение всех часовых поясов со смещениями GMT и UTC.

Автор оригинала: baeldung.

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 для перебора каждой записи в нашем наборе часовых поясов String id и преобразуем ее в список отформатированных часовых поясов с соответствующим смещением.

Для каждой из этих записей мы создаем экземпляр ZoneId с map(ZoneId::of).

3. Получение Смещений

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

Чтобы получить смещение UTC для любой заданной зоны, мы можем использовать Локальный набор данных Datetime() метод.

Также обратите внимание, что 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. Обеспечение Сопоставимости Зон

При желании мы также можем отсортировать часовые пояса по смещению.

Для этого мы будем использовать Компаратор зон класс:

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() для каждого смещенного базового перечисления значения и отобразив списки:

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 Stream и Date and Time .

Однако, если у нас есть Java 7 и перед проектом, мы все равно можем достичь того же результата, полагаясь на java.util.Часовой пояс класс с его 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 заключается в вычислении смещения.

Необработанное смещение мы получаем из Часового пояса() ‘s 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 .