【问题标题】:JSF convertDateTime with timezone in datatable数据表中带有时区的 JSF convertDateTime
【发布时间】:2011-10-30 15:35:54
【问题描述】:

尝试输出数据表中的项目列表,如下所示:

<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>

它总是以格林威治标准时间格式化时间。如果我使用字符串常量或不是数据表变量的 bean(如 '#{mybean.timeZone}'),它会按预期工作。

【问题讨论】:

    标签: jsf datatable timezone


    【解决方案1】:

    不幸的是,这就是&lt;f:xxx&gt; 标签的本质。当要构建视图时,将在实例化转换器的位置构建标签的单个实例。它的所有属性只被读取和设置一次。在构建视图时,#{item} 解析为 null(它仅在视图呈现期间可用),因此 timeZone 属性将为 null,然后默认为 UTC。当要渲染视图时,表中的每一行都会重复使用相同的转换器实例。

    有几种方法可以解决这个问题。我可以想到一个自定义转换器或一个 EL 函数。我认为自定义转换器毕竟是最好的,因为它也可以在输入组件中重用。以下启动示例应该适合您(为简洁起见,空检查和省略):

    @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 &lt;o:converter&gt; 正好解决了这个问题,无需自定义转换器。

    <h:outputText value="#{item.time}">
        <o:converter converterId="javax.faces.DateTime" pattern="yyyy-MM-dd HH:mm:ssZ" timeZone="#{item.timeZone}" />
    </h:outputText>
    

    【讨论】:

    • 转换器 ID 仍必须在 omnifaces 转换器中固定。是否可以动态设置converterId
    猜你喜欢
    • 2013-12-15
    • 1970-01-01
    • 2018-04-09
    • 2012-09-03
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多