The JSF Core Tag f:convertDateTime can format java.util.Date objects. The Date class has many deprecated methods and with Java 8 come new classes to present local dates and times: LocalDateTime and LocalDate.
f:convertDateTime can not format LocalDateTime nor LocalDate.
Does anybody know, if there is an equivalent to the JSF core tag convertDateTime that can deal with LocalDateTime objects? Is support planned for a future release, or are alternative tags available?
Just write your own Converter and extend the javax.faces.convert.DateTimeConverter
- that way you can Reuse all the attributes that <f:convertDateTime>
supports. Also it will take care of Localization too. Unfortunately it's a bit more complicated to write a Converter with Attributes.
Create component
First write your own Converter that extends javax.faces.convert.DateTimeConverter
- just let the super-calls do all the work (including locale-stuff) and convert the result from/to LocalDate.
@FacesConverter(value = LocalDateConverter.ID)
public class LocalDateConverter extends DateTimeConverter {
public static final String ID = "com.example.LocalDateConverter";
@Override
public Object getAsObject(FacesContext facesContext, UIComponent uiComponent, String value) {
Object o = super.getAsObject(facesContext, uiComponent, value);
if (o == null) {
return null;
}
if (o instanceof Date) {
Instant instant = Instant.ofEpochMilli(((Date) o).getTime());
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalDate();
} else {
throw new IllegalArgumentException(String.format("value=%s could not be converted to a LocalDate, result super.getAsObject=%s", value, o));
}
}
@Override
public String getAsString(FacesContext facesContext, UIComponent uiComponent, Object value) {
if (value == null) {
return super.getAsString(facesContext, uiComponent,value);
}
if (value instanceof LocalDate) {
LocalDate lDate = (LocalDate) value;
Instant instant = lDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);
return super.getAsString(facesContext, uiComponent, date);
} else {
throw new IllegalArgumentException(String.format("value=%s is not a instanceof LocalDate", value));
}
}
}
Then create a file LocalDateConverter-taglib.xml
in META-INF
:
<facelet-taglib version="2.2"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd">
<namespace>http://example.com/LocalDateConverter</namespace>
<tag>
<tag-name>convertLocalDate</tag-name>
<converter>
<converter-id>com.example.LocalDateConverter</converter-id>
</converter>
</tag>
</facelet-taglib>
And lastly, register the taglib in web.xml
:
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/META-INF/LocalDateConverter-taglib.xml</param-value>
</context-param>
Usage
To use the new Tag in your JSF-Page add the new Taglib xmlns:ldc="http://example.com/LocalDateConverter"
and use the tag:
<ldc:convertLocalDate type="both" dateStyle="full"/>