有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

UTC时区上的java hibernate+spring启动存储日期故障

我正在做一些测试,将UTC定义为我的应用程序的默认时区。首先,我希望我的日期时间值与UTC值一起存储

根据VLAD MIHALCEA(https://vladmihalcea.com/how-to-store-date-time-and-timestamps-in-utc-time-zone-with-jdbc-and-hibernate/)和https://moelholm.com/2016/11/09/spring-boot-controlling-timezones-with-hibernate/,我在我的属性文件中设置:

spring.jpa.properties.hibernate.jdbc.time_zone= UTC

为了测试我使用的是h2数据库,我创建了一个样本实体,其类型全部为java 8 dateTime

在我的liquibase配置中,它们的定义如下:

<column name="instant" type="timestamp"/>
<column name="local_date" type="date"/>
<column name="local_time" type="time"/>
<column name="offset_time" type="time"/>
<column name="local_date_time" type="timestamp"/>
<column name="offset_date_time" type="timestamp"/>
<column name="zoned_date_time" type="timestamp"/>

我想我在每个领域都使用了好的类型。它适用于除“local_time”、“offset_time”以外的所有字段,这些字段是时间sql类型,而不是时间戳

enter image description here

正如你所见,我在上午8:39(巴黎GMT+2)添加了这一行,时间戳具有良好的UTC值(上午6:38)。 但“本地时间”和“偏移时间”都有一个奇怪的值(上午7:39)

如果你们中的一些人知道为什么我的两个时间域不能正确存储值,我想知道为什么会出现这种行为

注:版本:

  • 冬眠:5.2.17。决赛
  • 弹簧靴:2.0.4。释放

我的示例实体用于插入数据:

import javax.persistence.*;
import java.io.Serializable;
import java.time.*;
import java.util.Objects;

@Entity
@Table(name = "avdev_myData")
public class MyData implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "instant")
    private Instant instant;

    @Column(name = "local_date")
    private LocalDate localDate;

    @Column(name = "local_time")
    private LocalTime localTime;

    @Column(name = "offset_time")
    private OffsetTime offsetTime;

    @Column(name = "local_date_time")
    private LocalDateTime localDateTime;

    @Column(name = "offset_date_time")
    private OffsetDateTime offsetDateTime;

    @Column(name = "zoned_date_time")
    private ZonedDateTime zonedDateTime;

共 (3) 个答案

  1. # 1 楼答案

    试试看:

    @SpringBootApplication
    public class YourApplication {
    
        @PostConstruct
        void started() {
            // set JVM timezone as UTC
            TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
        }
    }
    
  2. # 2 楼答案

    我在hibernate bug跟踪器中打开了一个问题,并找到了问题的答案

    对于本地时间,转换是相对于1970年1月1日,而不是我运行测试的那一天。所以DST没有得到处理

    根据Vlad Mihalcea的说法,我们必须使用LocalDateTime,因为我们知道日期,当然也知道它是否在DST时段

    这里有完整的回应: https://hibernate.atlassian.net/browse/HHH-12988?focusedCommentId=103750&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-103750

    问候

  3. # 3 楼答案

    以防在我的情况下决定使用MySQL与

    spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL57InnoDBDialect

    spring.datasource.url=jdbc:mysql://DBHOST:3306/DBNAME?useLegacyDatetimeCode=false&serverTimezone=UTC