数据表中带有时区的 JSF convertDateTime [英] JSF convertDateTime with timezone in datatable

查看:20
本文介绍了数据表中带有时区的 JSF convertDateTime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Trying to output a list of items in a datatable, like this:

<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}'),它会按预期工作.

It always formats the time in GMT. It works as expected if I use a string constant or a bean which isn't the datatable variable (like '#{mybean.timeZone}').

推荐答案

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

Unfortunately, that's the nature of <f:xxx> tags. When the view is to be built, a single instance of the tag is been built where the converter is instantiated. All of its attribtues are been read and set only once. At the moment the view is been built, the #{item} resolves to null (it's only available during rendering of the view), so the timeZone attribute will be null and then default to UTC. When the view is to be rendered, the very same converter instance is been reused for each row of the table.

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

There are several ways to solve this. I can think of a custom converter or an EL function. I think a custom converter is after all the best as it can then also be reused in input components. The following kickoff example should work out for you (nullchecks and on omitted for brevity):

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

这样,每次调用转换器时都会解析时区,而不是在构造过程中解析.

This way the timezone is resolved everytime the converter is invoked instead of during its construction.

更新:OmniFaces <o:converter> 完全解决了这个问题,无需自定义转换器.

Update: the OmniFaces <o:converter> solves exactly this problem without the need for a custom converter.

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

这篇关于数据表中带有时区的 JSF convertDateTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆