Недавно я создал виртуальную машину на 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 (книжный червь)
LocalTime.now(ZoneId.of("Asia/Taipei")).getHour()
работает?
if ( LocalTime.now( ZoneId.of( "Asia/Singapore" ) ).getHour() == 0 ) { … }
ЛокальноеВремя.сейчас()
Вы пропустили аргумент часового пояса при вызове этого метода. Таким образом, 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. Вместо этого укажите часовой пояс.
Есть ли причина, по которой вы не используете ZonedDateTime ?