Два разных результата про DateTimeZone.forID - PullRequest
0 голосов
/ 03 февраля 2020

У меня есть эта часть кода для получения идентификатора даты DateTimeZone

String timeZoneId = Calendar.getInstance().getTimeZone().getID();
DateTimeZone desTimeZone = DateTimeZone.forID(timeZoneId);

Когда эта часть кода выполняется в файле войны, я получил timeZoneId = "GMT + 01: 00"

Но когда я запускаю эту часть кода в основном методе, я получаю timeZoneId = "Europe / Paris"

Первая выдает исключение во второй строке: идентификатор зоны даты и времени 'GMT + 01: 00' не распознается

Не знаю, почему у меня два разных результата !!!

Как получить один и тот же результат в файле войны и в основном методе (Европа / Париж)?

Спасибо

Редактировать: добавить полный код метода:

publi c stati c DateTime toLocalDateTime (String gmtDate) {

if (StringUtils.isBlank(gmtDate)) {
    return null;
}

DateTime gmt = new DateTime(gmtDate, DateTimeZone.UTC);

String timeZoneId =  Calendar.getInstance().getTimeZone().getID();
DateTimeZone desTimeZone = DateTimeZone.forID(timeZoneId);
DateTimeZone.setDefault(desTimeZone);
LocalDateTime locDateTime = gmt.withZone(DateTimeZone.getDefault()).toLocalDateTime();

return locDateTime.toDateTime();
* * 1 020}

1 Ответ

2 голосов
/ 03 февраля 2020

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 этот класс представляет дату с указанием времени суток, но в нем отсутствует понятие зоны или смещения. Без этого контекста этот класс не может представлять момент.

...