tl; dr
Используйте современные классы java .time , которые заменили обе структуры, которые вы смешиваете в своем коде.
java.time.Instant
.parse( "2020-02-03T10:09:21.154Z" )
.atZone(
ZoneId.of( "Europe/Paris" )
)
Подробности
Вы не предоставили достаточно информации, чтобы поставить точный диагноз. Вам нужно было бы точно описать, как именно вы выполняете какой код.
И я не уверен, что стоит заняться этой проблемой по двум причинам:
- Вы используют
Calendar
, который является ужасным классом, частью оригинальных классов даты-времени, которые были годами go, вытесненными современными java .time классами, определенными в JSR 310. - Вы используете
DateTimeZone
из Joda-Time , предшественника java .time классов. Этот проект сейчас находится в режиме обслуживания.
java .time
Поэтому вместо него используйте java .time .
Получите текущий часовой пояс JVM по умолчанию.
ZoneId z = ZoneId.systemDefault() ;
Если вы хотите узнать смещение, используемое в данный момент в этой зоне, используйте ZoneRules
.
ZoneRules rules = z.getRules() ;
ZoneOffset offset = rules.getOffset( Instant.now() ) ;
Будьте внимательны относительно зоны и смещения. Смещение всего на несколько часов-минут-секунд вперед или позади основного меридиана. Смещение выглядит как +05:30
. Часовой пояс гораздо больше. Часовой пояс - это история прошлых, настоящих и будущих изменений в смещении, используемом людьми определенного региона. Название часового пояса имеет формат Continent/Region
.
Строки ISO 8601
Если задан текст в стандартном формате ISO 8601, например 2020-02-03T10:09:21.154Z
, следует понимать, что это представляет момент, как видно в UT C, то есть со смещением от UT C, равным нулю часов, минут и секунд. Z
на конце означает UT C и произносится как «зулу».
Разобрать такой ввод как java.time.Instant
. Этот класс представляет момент в UT C.
Instant instant = Instant.parse( "2020-02-03T10:09:21.154Z" ) ;
Чтобы увидеть этот момент через время часового пояса на стене, примените ZoneId
, чтобы получить ZonedDateTime
.
ZoneId z = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Объекты instant
и zdt
представляют один и тот же момент, одну и ту же точку на временной шкале.
Моменты
При отслеживании моментов указывайте c точки на временной шкале, никогда не используйте LocalDateTime
. И в средах Joda-Time, и в java .time этот класс представляет дату с указанием времени суток, но в нем отсутствует понятие зоны или смещения. Без этого контекста этот класс не может представлять момент.