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