Basic Joda Time converter (the code is absolutely superfluous for the context of this thread) :
@Named
@ApplicationScoped
@FacesConverter(forClass = DateTime.class)
public class DateTimeConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if (value == null || value.isEmpty()) {
return null;
}
try {
return DateTimeFormat.forPattern("dd-MMM-yyyy hh:mm:ss aa Z").parseDateTime(value).withZone(DateTimeZone.UTC);
} catch (IllegalArgumentException | UnsupportedOperationException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Message"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (value == null) {
return "";
}
if (!(value instanceof DateTime)) {
throw new ConverterException("Error");
}
try {
return DateTimeFormat.forPattern("dd-MMM-yyyy hh:mm:ss aa Z").print(((DateTime) value).withZone(DateTimeZone.forID("zoneId")));
} catch (IllegalArgumentException e) {
throw new ConverterException("Error", e); // Not required.
}
}
}
Why does it not work with a <p:calendar>
unless/until it is explicitly specified by using the converter
attribute?
<p:calendar converter="#{dateTimeConverter}" value="{bean.dateTimeValue}" .../>
Like other components, it is expected to work without mentioning the converter
attribute because the converter is decorated with
@FacesConverter(forClass = DateTime.class)
Is this feature not supported by <p:calendar>
?
Using PrimeFaces 5.2 and JSF 2.2.12.
Based on 5.2's
CalendarRenderer#encodeEnd()
, it usesCalendarUtils#getValueAsString()
to obtain the value for output. It indeed doesn't consult viaApplication#createConverter(Class)
if there's a converter by class.That confirms the behavior you observed. You'd best create an issue report to PrimeFaces guys which requests adding an
instanceof Date
check in place, and in the opposite case obtain the converter by class from the application something like below:This would indeed make sense given the increasing use of Java8's
java.time
API. There are by the way a few other places inCalendarRenderer
andCalendarUtils
where this could/should be implemented (and where they are actually performing aninstanceof
check, but not delegating it to the converter by class, if any).