【问题标题】:How to convert bytea to joda.time.DateTime or to Timestamp?如何将 bytea 转换为 joda.time.DateTime 或时间戳?
【发布时间】:2019-02-09 10:10:55
【问题描述】:

在我的数据库中,我有一列 bytea 类型。 我想检索该值并转换为日期时间。

这就是我的价值的样子:

\xaced0005737200166f72672e6a6f64612e74696d652e4461746554696d65b83c78646a5bddf90200007872001f6f72672e6a6f64612e74696d652e626173652e426173654461746554696d65fffff9e14f5d2ea30200024a0007694d696c6c69734c000b694368726f6e6f6c6f677974001a4c6f72672f6a6f64612f74696d652f4368726f6e6f6c6f67793b787000000168cd2d829e737200276f72672e6a6f64612e74696d652e6368726f6e6f2e49534f4368726f6e6f6c6f67792453747562a9c811667137502703000078707372001f6f72672e6a6f64612e74696d652e4461746554696d655a6f6e652453747562a62f019a7c321ae30300007870770500035554437878

我的数据库访问代码:

ResultSet resultSet = statement.executeQuery("SELECT * FROM public.history");
while (resultSet.next()) {
           System.out.printf("\n acquire_date: " +  resultSet.getString("acquire_Date") );
    }

如何将该值转换为 joda DateTime 或 java.util.Date? 我希望时间的格式是这样的:yyyy-MM-dd'T'HH:mm:ss'Z'

Database view

【问题讨论】:

  • bytea 是 PostgreSQL 中的字节数组。字节数组可以包含任何字节序列。您确定这些字节包含日期吗? (这似乎太长了)
  • Postgresql bytea 映射到 Java 字节数组。因此,将值作为 byte[] data = rs.getBytes("acquire_Date") 获取,然后转换为 long。长整数的值看起来很长

标签: java jdbc resultset bytea


【解决方案1】:

看起来您实际上将org.joda.time.DateTime 对象序列化为字节数组并以此类方式存储在数据库中(这是一种存储日期的可怕方式)。您只需要将这些数组反序列化回DateTime 对象。下面是一些使用您的示例值的概念验证代码:

import java.io.ByteArrayInputStream;
import java.io.ObjectInput;
import java.io.ObjectInputStream;

import javax.xml.bind.DatatypeConverter;

import org.joda.time.DateTime;

public class SerialTest {
    public static void main(final String... args) throws Exception {
        final String s = "aced0005737200166f72672e6a6f64612e74696d652e4461746554696d65b83c78646a5bddf90200007872001f6f72672e6a6f64612e74696d652e626173652e426173654461746554696d65fffff9e14f5d2ea30200024a0007694d696c6c69734c000b694368726f6e6f6c6f677974001a4c6f72672f6a6f64612f74696d652f4368726f6e6f6c6f67793b787000000168cd2d829e737200276f72672e6a6f64612e74696d652e6368726f6e6f2e49534f4368726f6e6f6c6f67792453747562a9c811667137502703000078707372001f6f72672e6a6f64612e74696d652e4461746554696d655a6f6e652453747562a62f019a7c321ae30300007870770500035554437878";
        final byte[] bytes = DatatypeConverter.parseHexBinary(s);
        // you would probably use bytes = resultSet.getBytes("acquire_Date") to get the byte array

        final ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        final ObjectInput in = new ObjectInputStream(bis);
        final DateTime dt = (DateTime) in.readObject();

        System.out.println(dt);
    }
}

结果:2019-02-08T12:55:38.398Z

另外请注意,在 java 中反序列化值时存在一些潜在的security issues

【讨论】:

  • 谢谢,成功了。我知道像这样存储在数据库中是很糟糕的。这就是为什么我想在应用程序中使用 java.util.Date 将所有列转换为时间戳的原因。您认为数据库中带有时间戳的 java.util.Date 是存储的好格式吗?
  • @SergiuFlavius 是的,在 pg 中你可能应该使用时间戳,有或没有时区。如果您想及时存储时刻,请使用带时区的时间戳,它对应于日期或即时(我认为也是 joda DateTime)。如果你想要一个特定的日期和时钟时间(可以根据时区表示不同的时刻),请使用不带时区的时间戳,它对应于 LocalDateTime。
猜你喜欢
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-20
相关资源
最近更新 更多