joda DateTimeFormat вопрос форматирования местного часового пояса - PullRequest
1 голос
/ 21 февраля 2020

Я начинаю с org.joda.time.DateTime и хочу вывести его со смещением часового пояса, эквивалентным местному часовому поясу. Это действительно для удобства пользователя, смотрящего на время своими глазами (вместо того, чтобы анализировать его с помощью правильного парсера ISO8601).

val tz = DateTimeZone.getDefault()
val formatter = JacksonJodaDateFormat(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ").withZone(tz))

Что я получаю, так это:

2020-02-01T05:00:00+0000

То, что я хочу, это:

2020-02-01T00:00:00-0500

То, что он выводит, действительно корректно для моего часового пояса, но я сказал ему .withZone (tz), и я подтвердил (через отладчик), что tz на самом деле Америка / Нью-Йорк.

Я использую йодатим 2.10.2. У меня также есть Джексон-формат-jodatime в миксе, но я попробовал это с Джексоном из l oop, и он ведет себя так же.

Документы говорят это:

When printing, this zone will be used in preference to the zone from the datetime that would otherwise be used. 

В противном случае будет напечатано UT C, но это не то, что я хочу, чтобы он делал.

Я неправильно интерпретирую слова Javadocs?

1 Ответ

1 голос
/ 21 февраля 2020

Если вы не возражаете против ответа Java (возможно, ваш фрагмент кода равен Kotlin?), Следующий текст отформатирует строку даты так, как вам нужно, и обработает сдвиги часовых поясов.

Для простоты я также не использовал библиотеку Джексона, как вы упомянули.

Очевидно, что приведенные ниже идентификаторы часовых поясов можно заменить на все, что вам нужно для начальной точки, например "UTC". Или по умолчанию системы, используя Joda-Time:

DateTimeZone defaultZone = DateTimeZone.getDefault();

Joda-Time

//
// Using Joda-Time 2.10.2:
//

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormat;

...

String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
String dateString;

DateTime dtOne = new DateTime("2020-02-21T09:30:45.678+00:00");
DateTimeFormatter fmt = DateTimeFormat.forPattern(pattern);

DateTime dtTwo = dtOne.withZone(DateTimeZone.forID("America/New_York"));
dateString = fmt.print(dtTwo);   // "2020-02-21T04:30:45-0500":

DateTime dtThree = dtOne.withZone(DateTimeZone.forID("Europe/Paris"));
dateString = fmt.print(dtThree); // "2020-02-21T10:30:45+0100"

java .time

Для Java 8 и далее, если вы можете использовать java.time, то withZoneSameInstant() соответственно сдвигает дату и время:

//
// Using java.time (Java 8 onwards):
//

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

...
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
String dateString;

DateTimeFormatter format = DateTimeFormatter.ofPattern(pattern);
LocalDateTime localDateTime = LocalDateTime.parse("2020-02-21T09:30:45.123");
ZonedDateTime zonedDateTimeA = localDateTime.atZone(ZoneId.of("Europe/Paris"));

dateString = zonedDateTimeA.format(format); // "2020-02-21T09:30:45+0100"

ZonedDateTime zonedDateTimeB = zonedDateTimeA
        .withZoneSameInstant(ZoneId.of("America/New_York"));    
dateString = zonedDateTimeB.format(format); // "2020-02-21T03:30:45-0500"

Для часового пояса по умолчанию, использующего java.time, это ZoneId.systemDefault().

Кроме того, этот - удивительный обзор.

Редактировать: Используйте java.time вместо Joda Time

В комментариях к вопросу упоминалось следующее , но необходимо указать в этом ответе также:

Если вы можете, вы обязательно должны использовать java.time сверх времени Joda.

с домашней страницы Joda Time :

Обратите внимание, что с Java SE 8 и далее пользователям предлагается перейти на java .time (JSR-310) - основную часть JDK, которая заменяет этот проект.

И из Стивен Коулборн , один из создателей Joda Time:

Я использую фразу, которая вдохновлена ​​java .time по мотивам Joda «Время», а не точный вывод, однако многие понятия будут знакомы.

...