OS irrelevent
Конфигурация вашей операционной системы не имеет значения.Большинство реализаций Java по умолчанию выбирают свой начальный часовой пояс по умолчанию из хост-ОС при запуске.Но определение часовых поясов хранится в реализации Java.
средство обновления часовых поясов Java
Так что вам нужно обновить часовой поясопределения в вашей реализации Java.В большинстве реализаций используется база данных tz , также известная как tzdata .
Для реализации Java под брендом Oracle Oracle предоставляет Средство обновления часовых поясов .Эта целевая страница имеет дату 2018-08, так что, возможно, изменения вашего часового пояса были включены.Но я предлагаю вам изучить более внимательно, чтобы проверить.
Для других реализаций, свяжитесь с поставщиком.Возможно, они предоставили обновленную версию JVM, чтобы включить новые tzdata.Или, возможно, они тоже предоставляют инструмент обновления.Или, возможно, вы можете заменить файл tzdata вручную.
Избегайте искажения зоны с кодом
Я настоятельно рекомендую вам избегать попыток искусственного изменения смещения самостоятельно в коде. Вы, вероятно, ошибетесь. Работа с датой и временем удивительно хитрая и запутанная.
Но если вы настаиваете, во-первых, избегайте ужасных старых устаревших классов даты и времени, таких как GregorianCalendar
& Calendar
& Date
.Они были вытеснены несколько лет назад JSR 310. Если вам необходимо взаимодействовать со старым кодом, который еще не обновлен до java.time , выполните свою работу в современных классах, а затем в конце выполните преобразование с помощью новых методов, добавленных в старыйклассы.
Используйте современные классы java.time , в частности:
Instant
(на мгновение в UTC) OffsetDateTime
(на мгновение со смещением от UTC часов-минут-секунд, но без часового пояса) ZonedDateTime
(на мгновение в определенном часовом поясе)
С помощью этих классов вы можете выполнить поиск переполнения стека для многих существующих примеров и объяснений.Вы должны сосредоточиться на OffsetDateTime
, ZoneOffset
(вместо ZoneId
) и Instant
, так как вы должныизбегайте ZonedDateTime
, если вы знаете, что ваш файл tzdata устарел.
тот же момент, другое время на настенных часах
OffsetDateTime::withOffsetSameInstant
OffsetDateTime odt = OffsetDateTime.parse( "2018-10-21T01:00:00.000-02:00" ) ;
ZoneOffset offset = ZoneOffset.ofHours( -3 ) ;
OffsetDateTime odt2 = odt.withOffsetSameInstant( offset ) ; // Same moment, same point on the timeline, different wall-clock time.
odt.toString (): 2018-10-21T01: 00-02: 00
odt2.toString (): 2018-10-21T00: 00-03: 00
В этом примере odt
и odt2
представляют один и тот же одновременный момент, одну и ту же точку на временной шкале.Если вы извлечете Instant
(значение в формате UTC), ваши результаты будут в тот же момент.Только время их настенных часов отличается.
Instant instant1 = odt.toInstant() ; // Adjust to UTC.
Instant instant2 = odt2.toInstant() ;
boolean sameMoment = instant1.equals( instant2 ) ;
instant1.toString (): 2018-10-21T03: 00: 00Z
instant2.toString (): 2018-10-21T03: 00: 00Z
sameMoment = true
Z
в конце означает UTC, нулевое смещение от UTC, +00:00
.Z
произносится как "зулу".Определяется стандартом ISO 8601 .
Другой момент, то же время на настенных часах
OffsetDateTime::withOffsetSameLocal
Напротив, вы можете задать время суток, таким образом представляя другой момент.Для этого используйте метод withOffsetSameLocal
.Помните, что вы меняете значение данных , вы перемещаетесь в другую точку на временной шкале.
OffsetDateTime differentMomentButSameTimeOfDay = odt. withOffsetSameLocal( offset ) ;
differentMomentButSameTimeOfDay.toString (): 2018-10-21T01: 00-03: 00
Извлеките момент, чтобы увидеть, что у нас другой момент.
Instant differentInstant = differentMomentButSameTimeOfDay.toInstant() ;
differentInstant.toString (): 2018-10-21T04: 00: 00Z
Обратите внимание на 4:00 UTC против 3:00 UTC, как показано выше.Этот момент здесь происходит через час после момента выше.Две разные точки на временной шкале.
Не пытайтесь выполнять эту работу до тех пор, пока вы полностью не поймете концепцию точек на временной шкале, и переход между точками будет полностью отличаться от настройки смещений.Практикуйтесь, прежде чем делать реальную работу.Нерешительные догадки приведут вас в мир боли и головной боли.
И, как я уже говорил выше, ваше время было бы гораздо лучше потратить на установку обновленных tzdata файлов, чем на взлом этих смещений.
Live code
См. Весь приведенный выше код Запустите live на IdeOne.com .
Обновите tzdata везде
Для достижения наилучших результатов вам следует обновить tzdata (или эквивалент) во всех этих различных местах:
- Ваши операционные системы
- Ваши JVM
- Ваши механизмы баз данных, такие как Postgres
- Любые библиотеки, объединяющие собственную информацию о часовом поясе (например: Joda-Time )
О java.time
Фреймворк java.time встроен в Java 8 и более поздние версии.Эти классы вытесняют старые классные устаревшие классы даты и времени, такие как java.util.Date
, Calendar
и & SimpleDateFormat
.
Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .
Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .
Вы можете обмениваться java.time объектами непосредственно с вашей базой данных.Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии.Нет необходимости в строках, нет необходимости в java.sql.*
классах.
Где получить классы java.time?
ThreeTen-Extra Проект расширяет java.time дополнительными классами.Этот проект является полигоном для возможных будущих дополнений к java.time.Здесь вы можете найти несколько полезных классов, таких как Interval
, YearWeek
, YearQuarter
и more .