尝试输出数据表中的项目列表,如下所示:
<t:dataTable value="#{mybean.list}" var="item">
<h:column>
<h:outputText value="#{item.time}">
<f:convertDateTime pattern="yyyy-MM-dd HH:mm:ssZ" timeZone="#{item.timeZone}" />
</h:outputText>
</h:column>
</t:dataTable>
它始终以GMT格式化时间。如果我使用字符串常量或不是数据表变量的bean(如'#{mybean.timeZone}'),它会按预期工作。
答案 0 :(得分:25)
不幸的是,这是<f:xxx>
标签的性质。在构建视图时,将构建转换器实例化的标记的单个实例。它的所有属性都只被读取和设置一次。在构建视图时,#{item}
会解析为null
(仅在呈现视图时才可用),因此timeZone
属性将为null
,然后默认为UTC。当要渲染视图时,对表的每一行重用相同的转换器实例。
有几种方法可以解决这个问题。我可以想到自定义转换器或EL功能。我认为自定义转换器是最好的,因为它也可以在输入组件中重用。下面的启动示例应该适用于您(nullchecks和为简洁而省略):
@FacesConverter("extendedDateTimeConverter")
public class ExtendedDateTimeConverter extends DateTimeConverter {
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
setPattern((String) component.getAttributes().get("pattern"));
setTimeZone(TimeZone.getTimeZone((String) component.getAttributes().get("timeZone")));
return super.getAsObject(context, component, value);
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
setPattern((String) component.getAttributes().get("pattern"));
setTimeZone(TimeZone.getTimeZone((String) component.getAttributes().get("timeZone")));
return super.getAsString(context, component, value);
}
}
可以用作
<h:outputText value="#{item.time}">
<f:converter converterId="extendedDateTimeConverter" />
<f:attribute name="pattern" value="yyyy-MM-dd HH:mm:ssZ" />
<f:attribute name="timeZone" value="#{item.timeZone}" />
</h:outputText>
这样,每次调用转换器时都会解析时区,而不是在构造期间解析时区。
更新:OmniFaces <o:converter>
无需自定义转换器即可解决此问题。
<h:outputText value="#{item.time}">
<o:converter converterId="javax.faces.DateTime" pattern="yyyy-MM-dd HH:mm:ssZ" timeZone="#{item.timeZone}" />
</h:outputText>