将 Hibernate 从 5.2 升级到 6.2.0.CR4 后,在 PostgreSQL v13 上,列数据类型 =“timestamp with time zone”,ex 值:“2023-04-13 04:42:16.992755-04”,定义为 java.sql. time.ZonedDateTime,UTC 偏移量显示字母“Z”而不是“UTC”。
@Getter
@Setter
@ToString
@Column(name="updated_at")
private ZonedDateTime updatedAt;
Apr. 13, 2023 04:46p.m. Z
Apr. 13, 2023 04:42p.m. Z
Apr. 12, 2023 04:13p.m. Z
Apr. 12, 2023 04:13p.m. Z
application.properties(springboot v3.x)
spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.jpa.properties.hibernate.timezone.default_storage=NORMALIZE_UTC
感谢帮助, --vs
解决方案(如果它对某人有帮助):
<p:column>
<h:panelGroup id="auditUpdatedAt">
<h:outputText value="Converted ZDT value">
<f:convertDateTime type="zonedDateTime" pattern="MMM dd, yyyy hh:mma"/>
</h:outputText>
</h:panelGroup
</p:column>
转换器后端部分:
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Locale;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.component.UIComponent;
import jakarta.faces.context.FacesContext;
import jakarta.faces.convert.Converter;
import jakarta.faces.convert.ConverterException;
public class ZonedDateTimeConverter implements Converter<Object> {
@Override
public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
if (modelValue == null) {
return "";
}
if (modelValue instanceof ZonedDateTime) {
return getFormatter(context, component).format((ZonedDateTime) modelValue);
} else {
throw new ConverterException(new FacesMessage(modelValue + " is not a valid ZonedDateTime"));
}
}
@Override
public Object getAsObject(FacesContext context, UIComponent component, String submittedValue) {
if (submittedValue == null || submittedValue.isEmpty()) {
return null;
}
try {
return ZonedDateTime.parse(submittedValue, getFormatter(context, component));
} catch (DateTimeParseException e) {
throw new ConverterException(new FacesMessage(submittedValue + " is not a valid zoned date time"), e);
}
}
private DateTimeFormatter getFormatter(FacesContext context, UIComponent component) {
return DateTimeFormatter.ofPattern(getPattern(component), getLocale(context, component));
}
private String getPattern(UIComponent component) {
String pattern = (String) component.getAttributes().get("pattern");
if (pattern == null) {
throw new IllegalArgumentException("pattern attribute is required");
}
return pattern;
}
private Locale getLocale(FacesContext context, UIComponent component) {
Object locale = component.getAttributes().get("locale");
return (locale instanceof Locale) ? (Locale) locale
: (locale instanceof String) ? new Locale((String) locale)
: context.getViewRoot().getLocale();
}
}
faces-config.xml
<converter>
<converter-id>zonedDateTimeConverter</converter-id>
<converter-class>com.XXX.ZonedDateTimeConverter</converter-class>
</converter>