基本转换器(仅仅是原型)在String
和java.time.LocalDateTime
之间来回转换。
@FacesConverter("localDateTimeConverter")
public class LocalDateTimeConverter implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return ZonedDateTime.parse(submittedValue, DateTimeFormatter.ofPattern(pattern, Locale.ENGLISH).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime());
} catch (IllegalArgumentException | DateTimeException e) {
throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, null, "Message"), e);
}
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
if (modelValue == null) {
return "";
}
if (!(modelValue instanceof LocalDateTime)) {
throw new ConverterException("Message");
}
Locale locale = context.getViewRoot().getLocale();
return DateTimeFormatter.ofPattern(pattern, locale).withZone(ZoneId).format(ZonedDateTime.of((LocalDateTime) modelValue, ZoneOffset.UTC));
}
}
提交给数据库的日期时间应基于Locale.ENGLISH
。因此,它在getAsObject()
中是常量/静态。
要从数据库检索即要呈现给最终用户的日期时间基于用户选择的所选区域。因此,Locale
中的getAsString()
是动态的。
日期时间是使用<p:calendar>
提交的,但未进行本地化以避免麻烦。
这将按预期工作,除非在转换/验证期间提交的<p:calendar>
组件或提交的同一表单上的某些其他组件失败,在这种情况下,日历组件将预先填充本地化日期-time除非将给定getAsObject()
中的本地化日期时间手动重置为默认语言环境,否则在后续所有提交表单的尝试中都无法在<p:calendar>
中进行转换。
以下内容将传递提交表单的第一次尝试,因为没有转换/验证违规。
但是,如果其中一个字段中存在转换错误,则如下所示
然后日历组件中的日期都将根据所选的区域设置(hi_IN
)进行更改,因为其中一个字段中存在转换错误,显然无法在{{1}中转换在后续尝试中,如果在通过为字段提供正确的值来修复转换错误后尝试提交包含组件的表单。
有什么建议吗?
答案 0 :(得分:1)
在转换器的getAsString()
中,您使用视图的区域设置来格式化日期。
Locale locale = context.getViewRoot().getLocale();
为了使用特定于组件的区域设置,必须将其作为组件属性提供。这是一个示例,前提是<locale-config><default-locale>
中的faces-config.xml
设置为en
。
<p:calendar ... locale="#{facesContext.application.defaultLocale}">
在转换器中,您可以按如下方式提取它:
Locale locale = (Locale) component.getAttributes().get("locale");
同时改变了转换器的基本转换器示例,以便将其正确考虑在内:How to use java.time.ZonedDateTime / LocalDateTime in p:calendar。