当前位置: 首页 > 知识库问答 >
问题:

如何为Spring Boot JPA时间戳指定UTC时区

汪晨
2023-03-14

环境

  • Spring Boot Starter Data JPA 1.4.2
  • Eclipselink 2.5.0
  • PostgreSQL 9.4.1211.jre7
@Column(name = "some_date", nullable = false)
private Timestamp someDate;
new java.sql.Timestamp(System.currentTimeMillis())

我查看了数据库,时间戳包含我的本地时区日期时间,但我想用UTC存储它。这是因为我的默认时区设置为'Europe/Brussely',JPA/JDBC在将我的java.sql.timestamp对象放入数据库之前将其转换为我的时区。

发现了不理想的解决方案

>

  • timezone.setdefault(timezone.gettimezone(“etc/utc”));具有我想要实现的效果,但它并不适合,因为它不是特定于我的服务的。即。它会影响整个JVM或当前线程加上子线程。

  • 共有1个答案

    訾高明
    2023-03-14

    对于这个问题,我能找到的最合适的解决方法是使用AttributeConverter将Java8ZonedDateTime对象转换为Java.sql.timestamp对象,这样它们就可以映射到PostgreSQLTimestamp没有时区类型。

    需要AttributeConverter的原因是Java8/Joda time date time类型与JPA尚不兼容。

    AttributeConverter如下所示:

    @Converter(autoApply = true)
    public class ZonedDateTimeAttributeConverter implements AttributeConverter<ZonedDateTime, Timestamp> {
    
        @Override
        public Timestamp convertToDatabaseColumn(ZonedDateTime zonedDateTime) {
            return (zonedDateTime == null ? null : Timestamp.valueOf(zonedDateTime.toLocalDateTime()));
        }
    
        @Override
        html" target="_blank">public ZonedDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
            return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime().atZone(ZoneId.of("UTC")));
        }
    
    }
    

    这允许我将不具有时区信息的数据库时间戳读取为具有UTC时区的ZonedDateTime对象。这样,无论应用程序运行在哪个时区,我都可以在数据库中看到准确的日期时间。

    由于tolocaldateTime()也应用系统默认的时区转换,所以这个attributeConverter基本上取消了JDBC驱动程序应用的转换。

    实际情况是,如果您在一个时区(即使是UTC)上存储日期时间信息,那么Timestamp没有timezonePostgreSQL类型是错误的选择。正确使用的数据类型是Timestamp with timezone,其中包含时区信息。这里有更多关于这个话题的信息。

    那么您可能对以下事实感兴趣:您至少需要jackson-datatype-jsr310依赖项的2.6.0版本才能进行序列化。在这个答案中有更多关于这一点的内容。

     类似资料:
    • 问题内容: 我正在寻找将UTC时间字符串转换为Unix时间戳的选项。 我拥有的字符串变量是,需要将其转换为unix时间戳,例如 任何想法如何做到这一点? 问题答案: 首先,unix时间戳没有时间,但以UTC为单位。 在包有功能解析与预计解析时的布局。布局是从参考时间开始构造的。因此,在您的情况下,布局应为。使用Parse之后,您将获得一个可以调用Unix来接收Unix时间戳的结构。

    • 我正在尝试使用Joda在一个简单的Java程序中获取UTC时间戳: 程序输出如下: 毫秒值是正确的UTC时间(即用时区确认)第二个值是时区。 我需要的是UTC值不变为(即独立于TZ),用于数据库写入。这可能吗? 我知道是本地日期(GMT-4),是UTC(GMT-0)。日期的输出值如下: 我尝试了所有组合,试图将的UTC值作为java.sql.TimeStamp: 用于测试的打印输出: 第一行是正确

    • 问题内容: 我正在使用MongoDB来存储我的数据。Mongo默认将时间戳存储在UTC中。我们在不同时区处理数据。我正在努力将UTC时间戳转换为PDT或IST时间戳。 试图构造一种方法来传递时区(将我的时间戳转换为时区)和timestamp(UTC)。返回指定时区的时间戳的方法。 问题答案: 您可以使用带有所需时区的dateformat并将其应用于日期

    • 我选择“无时区”是因为我知道我的应用程序使用的所有时间戳总是UTC。就我得到的文档而言,“with timestamp”的唯一区别是,我可以提供其他时区的值,然后将其转换为UTC。然而,我想避免这样的自动转换,因为如果我知道我的值是UTC,它们几乎没有任何好处。 当我在测试表中添加新记录并使用pgAdmin查看表的内容时,我可以看到插入日期已正确地保存为UTC格式。 但是,当我尝试使用JDBC选择

    • 但是,当我在数据库中查找时,存储的时间是由数据库时区与UTC的差值得出的。例如,当我的数据库在UTC+1运行时,运行上面的代码保存“08:00z”,数据库中的时间戳显示为09:00。 datetime的getMillis方法说“从1970-01-01t00:00:00z的Java纪元获取datetime瞬间的毫秒。”MySql的时间戳显示:“MySql将时间戳值从当前时区转换为UTC以存储,然后从

    • 问题内容: 我有一个毫秒本地本地时间戳,我想将其转换为毫秒本地UTC时间戳。快速浏览一下文档,看起来像这样工作: 有一个更好的方法吗? 问题答案: 使用a 来获取本地纪元处的偏移量,然后将其添加到本地纪元时间戳中。