Search code examples
jsfdatetimetimejsf-2.2prettytime

Using the pretty time library to show a time in a human readable format in JSF


I happened to use pretty time 1.0.6 to display an interval between two points in time in a human readable format.

There is an in-built JSF converter,

com.ocpsoft.pretty.time.web.jsf.PrettyTimeConverter

but it supports only java.util.Date objects.

I happened to use the following converter for org.joda.time.DateTime

@ManagedBean
@ApplicationScoped
public final class PrettyJodaTimeConverter extends PrettyTimeConverter
{
    @Override
    public String getAsString(final FacesContext context, final UIComponent component, final Object value)
    {
        if (value instanceof DateTime) {
            return super.getAsString(context, component, ((DateTime) value).toDate());
        } else {
            return super.getAsString(context, component, value);
        }
    }
}

This displays an interval, for example, "4 hours ago" on <h:outputText>, for example

<h:outputText value="#{productInquiryManagedBean.lastInquiry}"
              converter="#{prettyJodaTimeConverter}"/>

But I need to display a message on <p:growl> (or <p:messages>, <h:messages>) based on a conditional check in a JSF managed bean. Therefore, this converter cannot be used (please suggest, if it can be used). Instead, I need to manually format it in the managed bean in question like so,

private DateTime lastInquiry;
private String emailId;
private Product product;

if(productInquiryService.isPeriodExpired(30, emailId, product))
{
    lastInquiry=productInquiryService.getDateTimeOfLastInquiry(email, product);

    Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
    PrettyTime time=new PrettyTime(lastInquiry.toDate(), locale);
    time.setLocale(locale);

    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, Utility.getMessage("faces.message.error"), Utility.getMessage("inquiry.min.time.expire", time.format(new Date()))));
}

This displays a message on <p:growl> like - "You made an inquiry 4 hours from now".

Can this message format be changed to "You made an inquiry 4 hours ago" exactly as displayed on <h:outputText> as shown above?

Also, the interval format displayed here is not localized to a particular locate from a resource bundle. It always seems to be using its default locale. The message produced by PrettyTime#format() should be localized.


I was passing wrong parameters to the constructor. Hence the wrong message indicating a future time. They should be like as follows.

PrettyTime time=new PrettyTime(new Date(), locale);
time.format(lastInquiry.toDate());
//lastInquiry is fetched from the database which a customer made an inquiry on.

It now displays the correct (past time) format like "4 hours ago".

Regarding the locale I was looking for was HI (actually hi_IN, Hindi in India) is not available in the resource bundles (in the com.ocpsoft.pretty.time.i18n package) supplied in the library even though it is mentioned there in the i18n and multiple-languages support section.


Solution

  • I was passing wrong parameters to the constructor. Hence the wrong message indicating a future time. They should be like as follows.

    PrettyTime time=new PrettyTime(new Date(), locale);
    time.format(lastInquiry.toDate());
    //lastInquiry is fetched from the database which a customer made an inquiry on.
    

    The locale HI (for Hindi) and many others are available in the latest version 3.2.5 final.


    The JSF converter,

    com.ocpsoft.pretty.time.web.jsf.PrettyTimeConverter
    

    has been repackaged to

    org.ocpsoft.prettytime.jsf.PrettyTimeConverter
    

    and has been moved to a separate jar file prettytime-integration-jsf.

    In addition to the core jar file, this jar file is also needed, if you want to use this converter in JSF.