Функция Omnifaces of:secondsBetween EL не может быть преобразована в HH:mm:ss с помощью of:formatDate

Добрый день

Мне нужно отобразить дельта-время как разницу между двумя экземплярами java.date.Util в формате «ЧЧ: мм: сс».

Библиотека Omnifaces кажется очень удобной при вычислении разницы в секундах между этими двумя экземплярами java.date.Util, которые всегда будут в один и тот же день.

Одно значение задается с помощью компонента календаря Primefaces в верхней части файла .xhtml следующим образом:

<p:outputLabel for = "datetime" value = "Marathon Race Start: "/>
<p:calendar id = "datetime" value = "#{resultsView.marathonStart}" pattern = "yyyy/MM/dd HH:mm:ss">
        <p:ajax event = "change" immediate = "true" update = "marathon_results_form:results_all_datatable"/>
</p:calendar>

И затем результаты отображаются в таблице данных Primefaces, как показано ниже (только столбец времени, показанный, поскольку все остальные столбцы работают правильно):

<p:column headerText = "Time - Completed" style = "text-align: center; align-content: left">
    <c:set var = "raceTime" value = "#{of:secondsBetween(resultsView.marathonStart,allResults.dateTimeStamp)}"/>
    #{of:formatDate(raceTime, 'HH:mm:ss')}
</p:column>

Приведенный выше фрагмент кода выдает ошибку времени выполнения, указывающую:

cannot convert of type class java.lang.Long to class java.util.Date

Если я удалю Omnifaces:

#{of:formatDate(raceTime, 'HH:mm:ss')}

И заменить только:

#{raceTime}

Преобразование всего столбца затем в:

<p:column headerText = "Time - Completed" style = "text-align: center; align-content: left">
    <c:set var = "raceTime" value = "#{of:secondsBetween(resultsView.marathonStart,allResults.dateTimeStamp)}"/>
    #{raceTime}
</p:column>

Это действительно работает правильно, показывая количество секунд как long в столбце таблицы; и как только время начала обновляется через календарь Primefaces, количество секунд как лонг обновляется в реальном времени в таблице; именно так, как должно.

Итак, как я могу в EL (используя JSF 2.3.5.SP1 на WildFly 15) преобразовать эти длинные значения в формат «ЧЧ: мм: сс»?

Обновлено:

Я знаю, что это можно легко сделать, передав длинное значение raceTime методу управляемого компонента и вернув строку из компонента; однако, если это можно сделать более кратко с помощью EL или Omnifaces, я бы предпочел следовать этому подходу.

Работает ли он с использованием простой таблицы данных jsf? Если это так, это не связано с PrimeFaces или даже с простым «h: outputText» без каких-либо данных, скорее всего, не тогда, когда я смотрю на ошибку. Кажется, вы ожидаете, что Long можно преобразовать в дату, а в соответствии с ошибкой это невозможно. Функция называется formatDate, а не convertLongInSecondsToHoursAndMinutes.

Kukeltje 12.03.2019 10:00

Не по теме: если бы это вообще работало, можно было бы сделать это в одном EL без лайка c:set#{of:formatDate(of:secondsBetween(resultsView.marathonStart,‌​allResults.dateTimeS‌​tamp), 'HH:mm:ss')}?

Kukeltje 12.03.2019 10:01

@Kukeltje Спасибо, что нашли время ответить. Я не могу использовать таблицу данных JSF, потому что требование включает функциональность, предоставляемую таблицей данных Primefaces из коробки. Без использования c:set форма не отображается во время выполнения (возможно, из-за того, что теги Omnifaces не любят быть вложенными в EL (в примере с сайта Omnifaces также используется c:set) - это означает, что ваш второй ответ делает все в одном происходит сбой во время выполнения. Функции formatDate и/или formatDateTime EL ожидают преобразования даты (с указанием года, месяца и дня). Он не может преобразовать дельта-длинное (4792L) количество секунд в ЧЧ: мм: сс

Letholdrus 12.03.2019 10:28

ПОПРОБУЙ, ПОПРОБУЙ, ПОПРОБУЙ, сузь проблему, я нигде не говорил, что ты должен использовать h:datatable в продакшене... Вздох...

Kukeltje 12.03.2019 10:30

@Kukeltje, я просмотрел приведенные ниже ссылки и лично считаю, что управление преобразованием, например, 4777L в HH:mm:ss в управляемом bean-компоненте в этом случае является лучшим. Все остальные «formatDate» (из стандартного JSF или Omnifaces) нуждаются в правильной дате, которая представляет собой очень большое количество секунд с начала эпохи. Не имея необходимости иметь дело с часовыми поясами и т. д., Преобразование 4777L в метод bean-компонента, возвращающий строку, кажется более надежным методом, поскольку не используются часовые пояса или эпохи. Надеялся, что JSF EL сможет сделать это только длинным; отсюда и вопрос ;)

Letholdrus 12.03.2019 10:36
«преобразование, например, 4777L в HH:mm:ss в управляемом bean-компоненте в этом случае является лучшим». Правильно... Или напишите свою собственную функцию... Несложно (например, посмотрите исходный код omnifaces). Вы даже можете зарегистрировать ее как патч в запросе на включение для улучшения Omnifaces.
Kukeltje 12.03.2019 10:39

@Kukeltje Спасибо, Kulkeltje, я постараюсь сделать это ..

Letholdrus 12.03.2019 10:41

Я немного улучшил ответ. Пожалуйста, проверь это

Kukeltje 12.03.2019 10:42
Работа с датами и временем в языке Java
Работа с датами и временем в языке Java
Работа с датами и временем в языке Java была сильно переработана начиная с версии Java 8 и далее с появлением библиотеки java.time.
0
8
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В соответствии с of:formatDate он ожидает java.util.Date, а не java.lang.Long, поэтому следует ожидать приведения класса, поскольку возвращаемое значение of:secondsBetween не является java.util.Date.

Итак, то, что вы испытываете, полностью соответствует вашим ожиданиям. См. «См. также» для возможного исправления, но делать это в бэк-бине тоже не неправильно (не менее сознательно, IMO). Кроме того, вы также можете написать свою собственную функцию EL, не слишком сложную.

Смотрите также

@Kukeltjie Спасибо, сейчас изучаю эти варианты.

Letholdrus 12.03.2019 10:29

Спасибо что нашли время ответить. Очень признателен. Я постараюсь сделать то, что вы просите.

Letholdrus 12.03.2019 10:46

Другие вопросы по теме