Date toString без преобразования часового пояса для MessageFormat

Я использую библиотека IBM MessageFormat для локализации входящей даты.

Задача здесь состоит в том, чтобы запустить несколько проверок даты, прежде чем показать ее конечному пользователю. Я получаю объект ZonedDateTime, и мне нужно убедиться, что он не выпадает на выходные, что я и делаю, используя функцию getDayOfWeek.

Моя проблема возникает, когда я пытаюсь преобразовать дату в строку с помощью MessageFormat. Поскольку MessageFormat принимает только объекты java.util.Date, я конвертирую свой ZonedDateTime -> Instant -> Date. К сожалению, этот метод приводит к тому, что мой понедельник становится воскресеньем, как показано ниже.

Я заметил, что эта потеря происходит при преобразовании Date. Это связано с тем, что объект Date.toString() вызывается MessageFormat, а первый использует часовой пояс JVM по умолчанию (в моем случае PST). В результате мой UTC неявно преобразуется в PST, и я теряю день.

Любые идеи, как решить эту проблему? Есть ли что-нибудь еще, что я могу передать в MessageFormat? Есть ли способ использовать Date, но не получить это нежелательное поведение? Есть ли другая библиотека локализации, которую я могу использовать?

Точка останова при отладке показывает нежелательное поведение


person Abdo Salem    schedule 23.06.2020    source источник
comment
Сама дата правильная. Он просто печатает его в PST, потому что метод toString() класса Date будет печатать его, используя местный часовой пояс.   -  person Hari Menon    schedule 23.06.2020
comment
@HariMenon верно, но это означает, что мой конечный пользователь видит воскресенье, а не понедельник, потому что MessageFormat будет использовать преобразованную дату. Я в основном всегда теряю день в этом неявном преобразовании.   -  person Abdo Salem    schedule 23.06.2020
comment
stackoverflow.com/q/11610802/829571 — примените требуемый часовой пояс к базовым форматам SimpleDateFormat.   -  person assylias    schedule 23.06.2020
comment
Я не думаю, что Дата позволяет вам сделать это. Глядя на документ MessageFormatter, похоже, что вы можете указать строку формата, чтобы отформатировать ее по своему желанию, например, argStyleText, который может принимать любой SimpleDateFormat. Так что, возможно, вы можете изменить строку формата форматирования   -  person Hari Menon    schedule 23.06.2020
comment
@HariMenon Я думаю, что передача argStyleText приведет к тому, что MessageFormatter также передаст его в базовый SimpleDateFormat. Проблема здесь в том, что этот базовый SimpleDateFormat не будет использовать часовой пояс, который я хочу. Что я действительно хочу, так это установить часовой пояс в этом SimpleDateFormat. Предложение assylias выглядит хорошо, но оно слишком многословно, чтобы продолжать перебирать все SimpleDateFormat в MessageFormat, особенно когда рекомендуется каждый раз создавать новый экземпляр. Мой лучший вариант сейчас - просто использовать SimpleDateFormats напрямую. Позвольте мне посмотреть, предлагает ли он локализации, которые я хочу.   -  person Abdo Salem    schedule 23.06.2020


Ответы (1)


Внутри MessageFormat использует объект DateFormat, но не позволяет установить его часовой пояс. @Assylias связал вопрос, где ответ пытается извлечь внутренний формат даты, установите его часовой пояс, а затем используйте MessageFormat как обычно, что решает проблему.

Однако я обнаружил, что это слишком многословно, особенно потому, что вам нужно каждый раз создавать новый MessageFormat (в отличие от повторного использования MessageFormat, для которого вы уже установили часовой пояс).

Я решил просто использовать SimpleDateFormat напрямую.

// I have a ZonedDateTime zonedDateTime that I want to print out.
final SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE, MM dd", locale);
dateFormat.setTimeZone(TimeZone.getTimeZone(zonedDateTime.getZone()));
final String formattedDateString = dateFormat.format(Date.from(zonedDateTime.toInstant()));

Затем я использую String.format, чтобы вставить отформатированную дату в большую строку. Надеюсь это поможет.

person Abdo Salem    schedule 23.06.2020
comment
Если вы форматируете дату вручную, почему бы вам не использовать DateTimeFormatter? Преобразование часового пояса больше не требуется. String formatted = DateTimeFormatter.ofPattern("EEEE, MM, dd", Locale.UK).format(zonedDateTime) - person assylias; 23.06.2020