Как мне отформатировать javax.time.Instant в виде строки в местном часовом поясе?
Как мне отформатировать javax.time.Instant
как строка в местном часовом поясе? Следующее переводит местный Instant
в UTC, а не в местный часовой пояс, как я ожидал. Удаление звонка toLocalDateTime()
делает то же самое. Как я могу получить местное время вместо этого?
public String getDateTimeString( final Instant instant )
{
checkNotNull( instant );
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
DateTimeFormatter formatter = builder.appendPattern( "yyyyMMddHHmmss" ).toFormatter();
return formatter.print( ZonedDateTime.ofInstant( instant, TimeZone.UTC ).toLocalDateTime() );
}
Примечание. Мы используем более старую версию 0.6.3 эталонной реализации JSR-310.
4 ответа
Прежде чем вы проголосуете против моего ответа, обратите внимание, что вопрос явно (и жирным шрифтом) относится к старой версии 0.6.3 эталонной реализации JSR-310! Я задал этот вопрос в декабре 2012 года, задолго до появления Java 8 и новой библиотеки дат!
Я разочаровался в классах JSR-310 DateTimeFormatter
а также ZonedDateTime
и вместо этого прибегают к старомодным java.util.Date
а также java.text.SimpleDateFormat
:
public String getDateTimeString( final Instant instant )
{
checkNotNull( instant );
DateFormat format = new SimpleDateFormat( "yyyyMMddHHmmss" );
Date date = new Date( instant.toEpochMillisLong() );
return format.format( date );
}
Отвечая на этот вопрос относительно почти законченной версии JDK1.8
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyyMMddHHmmss").withZone(ZoneId.systemDefault());
return formatter.format(instant);
Ключ в том, что Instant
не имеет никакой информации о часовом поясе. Таким образом, он не может быть отформатирован с использованием каких-либо шаблонов, основанных на полях даты / времени, таких как "yyyyMMddHHmmss". Указав зону в DateTimeFormatter
момент конвертируется в указанный часовой пояс во время форматирования, что позволяет правильно выводить его.
Альтернативный подход заключается в преобразовании в ZonedDateTime
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
return formatter.format(ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()));
Оба подхода эквивалентны, однако я бы выбрал первый, если бы мой объект данных был Instant
,
Почему вы ожидаете, что он будет использовать местный часовой пояс? Вы явно просите UTC:
ZonedDateTime.ofInstant(instant, TimeZone.UTC)
Просто укажите ваш местный часовой пояс:
ZonedDateTime.ofInstant(instant, TimeZone.getDefault())
Попробуй это:
String dateTime = DateTimeFormatter.ISO_ZONED_DATE_TIME.format(
ZonedDateTime.ofInstant(instant, ZoneId.systemDefault())
);
Это дает:
2014-08-25T21:52:07-07:00[America/Los_Angeles]
Вы можете изменить формат, используя что-то кроме DateTimeFormatter.ISO_ZONED_DATE_TIME
в качестве форматера. DateTimeFormatter имеет несколько предопределенных форматеров, или вы можете определить свой собственный.