Перевод между часовыми поясами в Java
Один и тот же миг на шкале UTC в Москве и в Токио
выглядит разными часами на циферблате. Метод
withZoneSameInstant сохраняет момент и меняет
только подпись пояса и локальные поля.
Пример: фиксированная отметка в UTC и ее вид в восточных поясах:
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime utc = ZonedDateTime.of(
2024, 10, 2, 12, 0, 0, 0, ZoneId.of("UTC")
);
ZonedDateTime moscow = utc.withZoneSameInstant(
ZoneId.of("Europe/Moscow")
);
ZonedDateTime tokyo = utc.withZoneSameInstant(
ZoneId.of("Asia/Tokyo")
);
System.out.println(utc);
System.out.println(moscow);
System.out.println(tokyo);
}
}
Метод withZoneSameLocal оставляет те же числа
на календаре и часах, но меняет зону. Момент на
шкале UTC при этом сдвигается. Такой прием нужен
редко, чаще при смене настроек отображения без
пересчета «стенного» времени:
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime wall = ZonedDateTime.of(
2024, 10, 2, 9, 30, 0, 0,
ZoneId.of("Europe/Moscow")
);
ZonedDateTime sameClock = wall.withZoneSameLocal(
ZoneId.of("Asia/Tokyo")
);
System.out.println(wall.toInstant());
System.out.println(sameClock.toInstant());
}
}
Для хранения и сравнения в базе обычно пишут
Instant, а зонированный вид строят при
показе пользователю
и выбранный ZoneId.
Возьмите текущий момент в системной зоне и выведите
те же часы и минуты, переведенные в UTC.
Объясните словами, изменится ли toInstant
после withZoneSameInstant и после
withZoneSameLocal.