Получение информации о часовом поясе в Android

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для получения информации о часовом поясе на устройстве под управлением Android, удобно использовать следующий код:

Java
Скопировать код
String timeZoneId = TimeZone.getDefault().getID();

Этот код вернёт вам идентификатор текущего часового пояса, например, "Europe/Moscow" или "America/New_York".

Кинга Идем в IT: пошаговый план для смены профессии

Погружение в класс TimeZone

Если вы желаете изучить больше возможностей работы с часовым поясом, класс TimeZone предоставляет различные методы, которые помогут узнать больше деталей о нём:

Java
Скопировать код
TimeZone tz = TimeZone.getDefault();
String displayName = tz.getDisplayName(); // Название, например, "Тихоокеанское стандартное время"
int rawOffset = tz.getRawOffset(); // Смещение от UTC в миллисекундах. Учитывайте этот параметр!

Если в вашем часовом поясе применяется летнее время:

Java
Скопировать код
boolean isInDST = tz.inDaylightTime(new Date()); // Применяется ли сейчас летнее время!

А как преобразовать смещение в часы? Вот так:

Java
Скопировать код
double utcOffsetHours = tz.getOffset(System.currentTimeMillis()) / 3600000.0;
// Знакомая ситуация из "Назад в будущее", не правда ли?

Как корректно передать смещение на сервер? Просто конвертируйте его в строку:

Java
Скопировать код
String formattedOffset = String.format(Locale.US, "%+.2f", utcOffsetHours);
// Шуточка для математиков: если число Пи равно 3.14, может ли его назвать Пирогом? 🍰

Взгляд на java.time API

Те, кто всегда следует за новинками, обязательно оценят API java.time. Вот, к примеру, класс ZoneId:

Java
Скопировать код
ZoneId zoneId = ZoneId.systemDefault();
// Выглядит похоже, но тут уже чувствуется дух java.time, правда?

А как быть, если у вас есть устройства на Android с API level ниже 26? Вам помогут библиотека ThreeTen Backport или десахаризация.

ОСТОРОЖНО: DateFormatter приближается

Для форматирования часового пояса пригодится DateTimeFormatter из пакета java.time.format:

Java
Скопировать код
String zoneName = ZonedDateTime.now().format(DateTimeFormatter.ofPattern("zzz"));

Остерегайтесь ловушек

Особенности системных настроек

Не забывайте: значение TimeZone по умолчанию зависит от системных настроек. Если пользователь изменил часовой пояс, то ваши настройки также поменяются.

Тайна летнего времени

Будьте внимательны: метод getOffset() учитывает летнее время. Чтобы всегда получать точное значение, проверьте соответствующий параметр с помощью функции inDaylightTime(Date date) для своих дат.

ВНИМАНИЕ! Ловушка

Обработка исключений, связанных с информацией о часовом поясе, может быть запутанной. Не стоит игнорировать её, чтобы избежать проблем при изменении правил часового пояса.

Визуализация

Можно представить процесс получения информации о часовом поясе так, как будто вы читаете местную газету в незнакомом городе:

Вы приехали в чужой город и, разумеется, взяли с собой свой Android:

Java
Скопировать код
TimeZone tz = TimeZone.getDefault(); // Вы нашли местную газету!

Теперь вы знаете местные новости, а ваш девайс знает текущее время. Оба вы подстроились под новый ритм.

Размышления на глубокую тему

Общение с серверами

Когда вы "пожимаете руки" с сервером для передачи информации о часовом поясе, говорите на языке, который он понимает, лучше всего — в формате ISO 8601:

Java
Скопировать код
Instant now = Instant.now();
ZoneOffset offset = ZoneId.systemDefault().getRules().getOffset(now);
String offsetString = offset.toString(); // Вот и ISO 8601 формат
// Старые добрые байты стали битами 😢

Сложности работы с разными часовыми поясами

Если вам приходится работать с несколькими часовыми поясами, поступайте систематически:

  • Храните данные о часовых поясах пользователей локально.
  • Для часовых поясов, отличающихся от вашего, используйте метод TimeZone.getTimeZone(String ID).
  • Убедитесь, что разница в часовых поясах корректно отображается в календаре и пользовательском интерфейсе.

Не забывайте о тестировании

В завершение всё же стоит добавить пару советов:

  • Следует проводить тестирование с учетом различных часовых поясов.
  • Моделирование перехода на летнее или зимнее время — это будущее здесь и сейчас!
  • Модульное тестирование поможет избежать неприятных сюрпризов, связанных с изменением времени.

Полезные материалы

  1. TimeZone | Android Developers — Официальная документация Android по классу TimeZone.
  2. TimeZone (Java Platform SE 7) — Больше информации о классе TimeZone в Java.
  3. Free Date, Time, and Timezone API — Сервис для работы с API часовых поясов.
  4. GitHub – dlew/joda-time-android: Joda-Time library for Android — Joda-Time для продвинутой работы со временем на Android.
  5. ICU User Guide | ICU Documentation — Международное руководство по использованию часового пояса в ICU.
  6. SimpleDateFormat (Java Platform SE 6) — Всё о форматировании и разборе дат/времени при помощи SimpleDateFormat.