Изменение часового пояса не приводит к тому, что LocalTime.now() возвращает другое значение, почему?

Недавно я создал виртуальную машину на Google Cloud Platform для круглосуточного запуска моего .jar, и часть моего кода выглядит так:

if (LocalTime.now().getHour() == 0)
    whenDateChanged();

Я заметил, что он запускается в 12:00 UTC+0, но я хочу, чтобы он запускался в 12:00 UTC+8, поэтому я использую эту команду в терминале, чтобы изменить часовой пояс моего сервера:

sudo timedatectl set-timezone "Asia/Taipei"

После перезагрузки сервера кадры whenDateChanged() запускаются в 8 утра по всемирному координированному времени (UTC+8). Почему это произошло?

Версия Java: 21.0.3
ОС: Debian GNU/Linux, 12 (книжный червь)

Есть ли причина, по которой вы не используете ZonedDateTime ?

Abra 18.07.2024 09:05

LocalTime.now(ZoneId.of("Asia/Taipei")).getHour() работает?

Sweeper 18.07.2024 09:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
112
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

вр; доктор

if ( LocalTime.now( ZoneId.of( "Asia/Singapore" ) ).getHour() == 0 ) { … }

Укажите часовой пояс в Java

ЛокальноеВремя.сейчас()

Вы пропустили аргумент часового пояса при вызове этого метода. Таким образом, Java неявно применил текущий часовой пояс JVM по умолчанию.

В зависимости от такого значения по умолчанию успех вашего приложения противопоставляется прихотям системного администратора, который может изменить это значение по умолчанию.

Вместо этого я предлагаю вам явно указать желаемый/ожидаемый часовой пояс.

Сначала получите название желаемого часового пояса. Реальные часовые пояса имеют название в формате Continent/Region.

Поскольку вы упомянули об интересе к смещению на восемь часов вперед от UTC, я произвольно выбрал Asia/Singapore. В настоящее время эта зона использует смещение +08:00.

ZoneId zoneId = ZoneId.of( "Asia/Singapore" ) ;
LocalTime timeNow = LocalTime.now( zoneId ) ;

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

Нет нет нет.

Просто игнорируйте часовой пояс вашего сервера. Напишите свой Java-код, чтобы всегда указывать желаемый/ожидаемый часовой пояс, как показано выше.

И, кстати, на серверах обычно должно быть установлено время UTC (смещение в ноль часов-минут-секунд). Программистам и системным администраторам следует научиться считать UTC (смещение нуля) единым истинным временем. Все часовые пояса — это всего лишь вариации.

Как правило, все ваши журналы, обмен данными, хранение данных и бизнес-логика должны осуществляться в формате UTC, если нет явной и явной причины иного. Я предлагаю программистам и системным администраторам держать на своих столах часы, настроенные на UTC. Попытка работать и переходить в/из вашего приходского часового пояса сбивает с толку, подвержена ошибкам и отвлекает. Находясь на работе, думайте в UTC.

После перезагрузки сервера кадры WhenDateChanged() запускаются в 8 утра по UTC+8. Почему это произошло?

Поскольку ваш текущий код неявно зависит от текущего часового пояса JVM по умолчанию, вам необходимо проверить текущий часовой пояс JVM по умолчанию, а не текущий часовой пояс по умолчанию операционной системы хоста.

System.out.println( ZoneId.systemDefault() );

Некоторые реализации JVM могут устанавливать текущий часовой пояс по умолчанию в соответствии с часовым поясом хостовой ОС, как это обнаружено при запуске. Но это не обязательно так. Например, администратор, запускающий JVM при развертывании, может указать часовой пояс, который JVM будет использовать по умолчанию. Я понятия не имею, что может делать Google Cloud Platform.

👉🏽 Реальное решение — не зависеть от текущего часового пояса по умолчанию хостовой ОС или текущего часового пояса по умолчанию JVM. Вместо этого укажите часовой пояс.

Другие вопросы по теме

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

Может ли один и тот же код, использующий HttpClient, скомпилироваться с Spring-5.x и 6.x?
Улучшите качество подписи, извлеченной с помощью OpenCV из отсканированного листа бумаги
Переверните последовательные нули в единицы за k операций, чтобы получить максимальное количество единиц, найдите максимальное количество единиц
Влияет ли расстояние между операторами, отступами и комментариями в коде на его временную и пространственную сложность?
Почему мой код не удаляет zip-файл, созданный моим модульным тестом?
Приложение Spring Boot не запускается после добавления интеграции с клавиатурой
Исключение в потоке «main» java.time.format.DateTimeParseException: текст «1 апреля 2022 г., 12:00:00:000AM» не удалось проанализировать по индексу 19
Создайте Map<Long, CustomObject> , повторяя List<CustomObject>
Предупреждение о попытке с ресурсами для закрытия Super OutputStream
Данные JSON не были полностью использованы