如何将 java.time.LocalTime 以毫秒映射到 java.sql.Time 以毫秒
How to map java.time.LocalTime with milliseconds to a java.sql.Time with miliseconds
如何将带秒 (micro/milli/nano) 的 java.time.LocalTime
转换为 java.sql.Time
?
我知道自从 spring-data-jpa
的 2.x 版本以来,那些类型 (JSR310) 有它们的自定义转换器映射到遗留 java.sql.Date
和 java.sql.Timestamp
但我有LocalTime
第二部分的分数有很多问题。
How to map java.time.LocalTime
to a 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
根本问题是当地时间代表一天中的特定时间:
例如7:30pm
不是 7:30pm今天或昨天,或从星期天算起的第十七周,就... 7:30pm.
而 java.sql.Time 表示特定日期的特定时间 。
它们在内部存储为 long,即特定日期之前或之后的毫秒数(IIRC 1970 年 1 月 1 日)。
因此,要将 LocalTime 转换为 java.sql.Time,您必须指定该时间适用的特定日期。
查看 LocalTime.atDate(LocalDate),其中 returns 一个 LocalDateTime。
似乎没有一个很好的简单方法来提取毫秒或 net 纳秒(自 1/1/1970 00:00:00)
也许尝试 .toEpochSecond(需要指定时区),然后将其乘以 1000 或 1000000,然后将其写入数据库,然后将其读回(以查看是否有效)。
或者:
你一直说你不想要日期 - 我明白了,但由于数据库不需要,你可以尝试存储 localTime.toNanoOfDay.
它将解释为 1/1/1970 的一天中的某个时间。
很可能您不希望从 LocalTime
转换为老式的 Time
。
如果您认为您需要一个 java.sql.Time
来存储到您的 SQL 数据库或对其进行查询,情况可能并非如此。如果您至少可以使用 Java 8 和至少 JDBC 4.2(或现代 JPA 实现),则可以直接对数据库使用 LocalTime
而无需转换。使用例如
yourPreparedStatement.setObject(7, yourLocalTime);
那你就没事了
如果您确实需要 java.sql.Time
、 shows the right and precise way to convert. The challenge is that the simple Time.valueOf(LocalTime)
loses the fraction of second. The docs,请说:
The nanosecond field from LocalTime is not part of the newly created Time object.
很明显,你不能拥有所有的纳秒,因为 Time
只有毫秒的精度。为什么他们不取毫秒(9 位纳秒值的前 3 位十进制数字),我不知道。安德烈亚斯。
如何将带秒 (micro/milli/nano) 的 java.time.LocalTime
转换为 java.sql.Time
?
我知道自从 spring-data-jpa
的 2.x 版本以来,那些类型 (JSR310) 有它们的自定义转换器映射到遗留 java.sql.Date
和 java.sql.Timestamp
但我有LocalTime
第二部分的分数有很多问题。
How to map
java.time.LocalTime
to ajava.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
根本问题是当地时间代表一天中的特定时间:
例如7:30pm
不是 7:30pm今天或昨天,或从星期天算起的第十七周,就... 7:30pm.
而 java.sql.Time 表示特定日期的特定时间 。
它们在内部存储为 long,即特定日期之前或之后的毫秒数(IIRC 1970 年 1 月 1 日)。
因此,要将 LocalTime 转换为 java.sql.Time,您必须指定该时间适用的特定日期。
查看 LocalTime.atDate(LocalDate),其中 returns 一个 LocalDateTime。
似乎没有一个很好的简单方法来提取毫秒或 net 纳秒(自 1/1/1970 00:00:00)
也许尝试 .toEpochSecond(需要指定时区),然后将其乘以 1000 或 1000000,然后将其写入数据库,然后将其读回(以查看是否有效)。
或者:
你一直说你不想要日期 - 我明白了,但由于数据库不需要,你可以尝试存储 localTime.toNanoOfDay.
它将解释为 1/1/1970 的一天中的某个时间。
很可能您不希望从 LocalTime
转换为老式的 Time
。
如果您认为您需要一个 java.sql.Time
来存储到您的 SQL 数据库或对其进行查询,情况可能并非如此。如果您至少可以使用 Java 8 和至少 JDBC 4.2(或现代 JPA 实现),则可以直接对数据库使用 LocalTime
而无需转换。使用例如
yourPreparedStatement.setObject(7, yourLocalTime);
那你就没事了
如果您确实需要 java.sql.Time
、Time.valueOf(LocalTime)
loses the fraction of second. The docs,请说:
The nanosecond field from LocalTime is not part of the newly created Time object.
很明显,你不能拥有所有的纳秒,因为 Time
只有毫秒的精度。为什么他们不取毫秒(9 位纳秒值的前 3 位十进制数字),我不知道。安德烈亚斯。