Search code examples
datejsfprimefacesjsf-2omnifaces

Omnifaces of:secondsBetween EL function cannot be converted to HH:mm:ss by of:formatDate


Good day

I need to display the delta time as the difference between two java.date.Util instances in the format 'HH:mm:ss'

The Omnifaces library seems very handy in calculating the amount of seconds difference between these two java.date.Util instances that will always be on the same day.

The one value is set using a Primefaces calendar component at the top of the .xhtml file like this:

<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>

And then the results are displayed in a Primefaces dataTable like below (only the time column shown as all other columns works correct):

<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>

The above snippet throws a runtime error stating:

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

If I remove the Omnifaces:

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

And replace with only:

#{raceTime}

Converting the whole column then to:

<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>

It indeed works correctly by showing the amount of seconds as a long in the table column; and as soon as the start time is updated via the Primefaces calendar, the amount of seconds as a long updates in real time in the table; exactly as it should.

So then, how can I in the EL (using JSF 2.3.5.SP1 on WildFly 15) convert those longs to the 'HH:mm:ss' format?

EDIT:

I know this can be easily done by passing the long raceTime to a managed bean's method and get a string back from the bean; however, if this can be done more concisely via EL or Omnifaces I would rather follow that approach.


Solution

  • According to the of:formatDate it expects a java.util.Date and not a java.lang.Long, so the classcast is to be expected since the return value of of:secondsBetween is not a java.util.Date.

    So what you experience is totally as expected. See the 'See also' for a possible fix, but doing it in a backing bean is not wrong either (not not less consice imo). In addition you can also write your own EL function, not too difficul

    See also