1. Обзор
Пользователи наших приложений могут быть требовательными, когда дело доходит до временных меток. Они ожидают, что наши приложения будут автоматически определять их часовые пояса и отображать метки времени в правильном часовом поясе.
В этом уроке мы рассмотрим несколько способов изменения часового пояса JVM . Мы также узнаем о некоторых подводных камнях, связанных с управлением часовым поясом.
2. Введение в Часовой пояс
По умолчанию JVM считывает информацию о часовом поясе из операционной системы. Эта информация передается в класс Часовой пояс , который хранит часовой пояс и вычисляет летнее время .
Мы можем вызвать метод getDefault, который вернет часовой пояс, в котором выполняется программа. Кроме того, мы можем получить список поддерживаемых идентификаторов часовых поясов из приложения с помощью TimeZone.getAvailableIDs() .
При именовании часового пояса Java полагается на соглашение об именовании базы данных tz .
3. Изменение часового пояса
В этом разделе мы рассмотрим несколько способов изменения часового пояса в JVM.
3.1. Установка переменной окружения
Давайте начнем с того, как мы можем использовать переменную среды для изменения часового пояса. Мы можем добавить или изменить переменную окружения TZ.
Например, в средах на базе Linux мы можем использовать команду export :
export TZ="America/Sao_Paulo"
После установки переменной окружения мы видим, что часовой пояс нашего запущенного приложения теперь America/Sao_Paulo:
Calendar calendar = Calendar.getInstance(); assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("America/Sao_Paulo"));
3.2. Установка аргумента JVM
Альтернативой настройке переменной среды является установка аргумента JVM user.timezone . Этот аргумент JVM имеет приоритет над переменной окружения TZ .
Например, мы можем использовать флаг -D при запуске нашего приложения:
java -Duser.timezone="Asia/Kolkata" com.company.Main
Аналогично, мы также можем установить аргумент JVM из приложения :
System.setProperty("user.timezone", "Asia/Kolkata");
Теперь мы видим, что часовой пояс-Азия/Калькутта:
Calendar calendar = Calendar.getInstance(); assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("Asia/Kolkata"));
3.3. Установка Часового пояса Из Приложения
Наконец, мы также можем изменить часовой пояс JVM из приложения, используя Часовой пояс класс . Этот подход имеет приоритет как над переменной среды, так и над аргументом JVM.
Установить часовой пояс по умолчанию очень просто:
TimeZone.setDefault(TimeZone.getTimeZone("Portugal"));
Как и ожидалось, часовой пояс сейчас Португалия :
Calendar calendar = Calendar.getInstance(); assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("Portugal"));
4. Подводные камни
4.1. Использование трехбуквенных идентификаторов часовых поясов
Несмотря на то, что для представления часового пояса можно использовать трехбуквенные идентификаторы, это не рекомендуется .
Вместо этого мы должны использовать более длинные имена, так как трехбуквенные идентификаторы неоднозначны. Например, ЭТО может быть Индийское Стандартное время, Ирландское Стандартное время или Израильское Стандартное время.
4.2. Глобальные настройки
Обратите внимание, что каждый из вышеперечисленных подходов устанавливает часовой пояс глобально для всего приложения. Однако в современных приложениях настройка часового пояса часто более тонка, чем это.
Например, нам, вероятно, нужно перевести время в часовой пояс конечного пользователя, и поэтому глобальный часовой пояс не будет иметь большого смысла. Если глобальный часовой пояс не нужен, рассмотрите возможность указания часового пояса непосредственно в каждом экземпляре даты и времени. Либо ZonedDateTime, либо OffsetDateTime-удобный класс для этого.
5. Заключение
В этом уроке мы объяснили несколько способов изменения часового пояса JVM. Мы увидели, что мы можем либо установить общесистемную переменную среды, изменить аргумент JVM, либо изменить его программно из нашего приложения.
Как обычно, все примеры, используемые в этой статье, доступны на GitHub.