如何将毫秒级的java.time.LocalTime映射到毫秒级的java.sql.Time

时间:2018-07-05 01:38:44

标签: java spring spring-boot spring-data-jpa java-time

如何将秒(微/毫/毫微秒)的java.time.LocalTime转换为java.sql.Time

我知道,自spring-data-jpa的2.x版本以来,这些类型(JSR310)都有其自定义转换器,它们映射到旧版java.sql.Datejava.sql.Timestamp,但是我遇到了很多问题加上LocalTime的第二部分的分数。

3 个答案:

答案 0 :(得分:2)

  

如何将java.time.LocalTime映射到java.sql.Time

这是不使用String作为中间值的一种方法。

java.time.LocalTime localTime = java.time.LocalTime.now();
long epochMilli = localTime.atDate(java.time.LocalDate.EPOCH)
                           .atZone(java.time.ZoneId.systemDefault())
                           .toInstant()
                           .toEpochMilli();
java.sql.Time sqlTime = new java.sql.Time(epochMilli);

System.out.println(localTime.format(DateTimeFormatter.ofPattern("HH:mm:ss.SSS")));
System.out.println(new SimpleDateFormat("HH:mm:ss.SSS").format(sqlTime));

输出

22:28:22.104
22:28:22.104

答案 1 :(得分:1)

基本问题是本地时间代表一天中的特定时间:

例如晚上7:30

今天或昨天晚上7:30,或者从星期日起十七周,晚上7:30。

而java.sql.Time表示在特定日期的特定时间。

内部将它们存储为 long ,即特定日期(IIRC 1970年1月1日)之前或之后的毫秒数。

因此要将LocalTime转换为java.sql.Time,您必须指定该Time适用的特定日期。

看看LocalTime.atDate(LocalDate),它返回一个LocalDateTime。

似乎没有一种很好的简单方法可以提取毫秒或 net 纳秒(自1970年1月1日00:00:00起)

也许尝试.toEpochSecond(需要指定一个时区),然后将其乘以1000或1000000,然后将其写入数据库,然后将其读回(以查看其是否有效)。


或者:

您一直在说您不想要日期-我知道,但是由于数据库不需要,您可以尝试存储localTime.toNanoOfDay。

它将被解释为1970年1月1日的一天中的某个时间。

答案 2 :(得分:0)

很有可能您不希望从LocalTime转换为老式的Time

如果您认为需要java.sql.Time来存储到SQL数据库或对其进行查询,则可能并非如此。只要您至少可以使用Java 8和JDBC 4.2(或现代的JPA实现),就可以直接对数据库使用LocalTime,而无需进行转换。例如使用

    yourPreparedStatement.setObject(7, yourLocalTime);

那你会没事的。

如果您确实需要java.sql.TimeAndres’ answer将显示正确且准确的转换方式。挑战在于简单的Time.valueOf(LocalTime)会损失秒的分数。 The docs说:

  

LocalTime的纳秒字段不属于新创建的Time对象。

很明显,由于Time仅具有毫秒级的精度,因此您无法拥有所有的纳秒级。我不知道为什么他们不花毫秒(9位纳秒值的前3个十进制数字)。安德里亚斯做到了。