JSF在datatable中使用时区转换DateDateTime [英] JSF convertDateTime with timezone in datatable

查看:154
本文介绍了JSF在datatable中使用时区转换DateDateTime的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 < t:dataTable value =# {mybean.list}var =item> 
< h:column>
< h:outputText value =#{item.time}>
< f:convertDateTime pattern =yyyy-MM-dd HH:mm:ssZtimeZone =#{item.timeZone}/>
< / h:outputText>
< / h:column>
< / t:dataTable>

它始终以GMT格式设置时间。如果我使用字符串常量或不是datatable变量的bean(如'#{mybean.timeZone}')),它的工作原理如下。

解决方案

不幸的是,这是< 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 模式));
setTimeZone(TimeZone.getTimeZone((String)component.getAttributes()。get(timeZone)));
return super.getAsString(context,component,value);
}

}

p>

 < h:outputText value =#{item.time}> 
< f:converter converterId =extendedDateTimeConverter/>
< f:attribute name =patternvalue =yyyy-MM-dd HH:mm:ssZ/>
< f:attribute name =timeZonevalue =#{item.timeZone}/>
< / h:outputText>

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




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

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


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>

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}').

解决方案

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.

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);
    }

}

which can be used as

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


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在datatable中使用时区转换DateDateTime的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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