Hibernate 6 列定义为“带有时区的时间戳”,在 ZonedDateTime 中不显示 UTC 偏移量

问题描述 投票:0回答:1

将 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”。

output example

@Getter
@Setter
@ToString

@Column(name="updated_at")
private ZonedDateTime updatedAt;

PostgreSQL column

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

6.2.0.CR4

application.properties(springboot v3.x)

spring.jpa.properties.hibernate.jdbc.time_zone=UTC
spring.jpa.properties.hibernate.timezone.default_storage=NORMALIZE_UTC
  • 在 Hibernate 5.2 上,时区是“UTC”而不是“Z”。

感谢帮助, --vs

postgresql hibernate primefaces jsf-2.2
1个回答
0
投票

解决方案(如果它对某人有帮助):

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

© www.soinside.com 2019 - 2024. All rights reserved.