К сожалению, такова природа тегов <f:xxx>
. Когда представление должно быть построено, создается один экземпляр тега, в котором создается экземпляр преобразователя. Все его атрибуты считываются и устанавливаются только один раз. В момент создания представления #{item}
преобразуется в null
(он доступен только во время рендеринга представления), поэтому атрибут timeZone
будет равен null
, а затем по умолчанию будет использоваться значение UTC. Когда представление должно быть отображено, один и тот же экземпляр преобразователя повторно используется для каждой строки таблицы.
Есть несколько способов решить эту проблему. Я могу подумать о специальном преобразователе или функции EL. Я думаю, что пользовательский преобразователь, в конце концов, лучше всего, поскольку его также можно повторно использовать во входных компонентах. Следующий стартовый пример должен сработать для вас (для краткости проверочные значения и on опущены):
@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>
19.08.2011