Вопрос по java, timezone – Получить значение смещения TimeZone из TimeZone без имени TimeZone

46

Мне нужно сохранить часовой пояс телефона в формате [+/-] чч: мм

Я использую класс TimeZone, чтобы справиться с этим, но единственный формат, который я могу получить, является следующим:

PST -05:00
GMT +02:00

Я бы предпочел не подставлять результат, есть ли какой-либо ключ или флаг опции, который я могу установить, чтобы получить только значение, а не имя этого часового пояса (GMT / CET / PST ...)?

Ваш Ответ

6   ответов
3

In#eger offse#  = ZonedDa#eTime.now().ge#Offse#().ge#To#alSeconds();

получить текущее смещение системного времени от UTC. Затем вы можете преобразовать его в любой формат, который вы хотите. Нашел это полезным для моего случая. Пример :h##ps://docs.oracle.com/javase/#u#orial/da#e#ime/iso/#imezones.h#ml

2
ZoneId here = ZoneId.of("Europe/Kiev");
ZonedDateTime hereAndNow = Instant.now().atZone(here);
String.format("%tz", hereAndNow);

подобное & quot; + 0300 & quot;

работает только в Android API 26 и выше, пользователи Android должны следить перед использованием
1

что это старое, но я решил дать свой вклад. Я должен был сделать это для проекта на работе, и это было мое решение.

У меня есть объект Building, который включает в себя часовой пояс, используя класс TimeZone, и хотел создать поля zoneId и смещения в новом классе.

Так что я сделал создать:

private String timeZoneId;
private String timeZoneOffset;

Затем в конструкторе я передал объект Building и установил эти поля следующим образом:

this.timeZoneId = building.getTimeZone().getID();
this.timeZoneOffset = building.getTimeZone().toZoneId().getId();

Таким образом, timeZoneId может равняться чему-то вроде & quot; EST & quot; И timeZoneOffset может равняться чему-то вроде "-05: 00"

Я бы не хотел, чтобы вы не

building.getTimeZone (). toZoneId (). getId () возвращает текст (например, «Европа / Осло»), а не смещение (например, «2»)
1

TimeZone только сTimeZone экземпляр иSystem.currentTimeMillis(), Затем мы можем конвертировать из миллисекунд в любую единицу времени, используяTimeUnit учебный класс.

Вот так:

public static int getOffsetHours(TimeZone timeZone) {
    return (int) TimeUnit.MILLISECONDS.toHours(timeZone.getOffset(System.currentTimeMillis()));
}

Or if you prefer the new Java 8 time API

public static ZoneOffset getOffset(TimeZone timeZone) { //for using ZoneOffsett class
    ZoneId zi = timeZone.toZoneId();
    ZoneRules zr = zi.getRules();
    return zr.getOffset(LocalDateTime.now());
}

public static int getOffsetHours(TimeZone timeZone) { //just hour offset
    ZoneOffset zo = getOffset(timeZone);
    TimeUnit.SECONDS.toHours(so.getTotalSeconds());
}
82

Нет, вы не т. Смещения само по себе недостаточно, вам нужно хранить полное имя / идентификатор часового пояса. Например, я живу в Осло, где мое текущее смещение составляет +02: 00, но зимой (из-за) это +01: 00. Точное переключение между стандартным и летним временем зависит от факторов, которые вы не хотите исследовать.

Так что вместо хранения+ 02:00 (или это должно быть+ 01:00?) Я храню"Europe/Oslo" в моей базе данных. Теперь я могу восстановить полную конфигурацию, используя:

TimeZone tz = TimeZone.getTimeZone("Europe/Oslo")

Хотите знать, какое у меня смещение часового пояса сегодня?

tz.getOffset(new Date().getTime()) / 1000 / 60   //yields +120 minutes

Однако то же самое в декабре:

Calendar christmas = new GregorianCalendar(2012, DECEMBER, 25);
tz.getOffset(christmas.getTimeInMillis()) / 1000 / 60   //yields +60 minutes

Достаточно сказать: сохраняйте имя или идентификатор часового пояса, и каждый раз, когда вы хотите отобразить дату, проверяйте текущее смещение (сегодня), а не сохраняйте фиксированное значение. Ты можешь использоватьTimeZone.getAvailableIDs() перечислить все поддерживаемые идентификаторы часовых поясов.

@johnvdenley: пожалуйста, задайте отдельный вопрос, не стесняйтесь разместить ссылку для продолжения здесь.
Большое обновление Томаш, однако, я могу попросить вас немного расширить. Я храню дату в Базе данных на сервере как UTC (очевидно), и я сохраняю свое имя TZ (в вашем примере «Европа / Осло») также в Базе данных на сервере. Я хочу передать дату обратно клиенту с примененным правильным смещением. Должен ли я (могу ли я?) Сделать это, или я должен передать дату и смещение отдельно? Проблема в том, что я использую GWT на клиенте, поэтому я не могу использовать java.util.TimeZone и поэтому не могу конвертировать & quot; Европа / Осло & quot; так как com.google.gwt.i18n.shared.TimeZone.createTimeZone (& quot; Европа / Осло & quot;) не работает !!
Нет, я взаимодействую с API, каким бы хорошим или плохим он ни был. Давайте не будем вдаваться в подробности. Они требуют, чтобы я отправил часовой пояс, например, чч: мм ... не знаю, я знаю. Mr Bean
@MrBean: по стечению обстоятельств я показал вам, что делать: если у вас уже естьTimeZone класс, просто позвониgetOffset() с текущей датой и преобразовать ее из миллисекунд в минуты. Затем отформатируйте вhh:mm.
Это был именно тот ответ, который я искал, очень хорошо представлен, спасибо!
64

@MrBean - у меня была похожая ситуация, когда мне приходилось вызывать сторонний веб-сервис и передавать текущее смещение часового пояса устройства Android в формате +/- чч: мм.

public static String getCurrentTimezoneOffset() {

    TimeZone tz = TimeZone.getDefault();  
    Calendar cal = GregorianCalendar.getInstance(tz);
    int offsetInMillis = tz.getOffset(cal.getTimeInMillis());

    String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
    offset = (offsetInMillis >= 0 ? "+" : "-") + offset;

    return offset;
} 

Похожие вопросы