如何将秒(微/毫/毫微秒)的java.time.LocalTime
转换为java.sql.Time
?
我知道,自spring-data-jpa
的2.x版本以来,这些类型(JSR310)都有其自定义转换器,它们映射到旧版java.sql.Date
和java.sql.Timestamp
,但是我遇到了很多问题加上LocalTime
的第二部分的分数。
答案 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.Time
,Andres’ answer将显示正确且准确的转换方式。挑战在于简单的Time.valueOf(LocalTime)
会损失秒的分数。 The docs说:
LocalTime的纳秒字段不属于新创建的Time对象。
很明显,由于Time
仅具有毫秒级的精度,因此您无法拥有所有的纳秒级。我不知道为什么他们不花毫秒(9位纳秒值的前3个十进制数字)。安德里亚斯做到了。