[英]How to convert java.time.Duration to java.sql.Time?
What is the best way to convert a java.time.Duration
-object to java.sql.Time
? 将
java.time.Duration
转换为java.sql.Time
的最佳方法是什么?
I am getting an ISO8601-String like PT15M51S
and Duration.parse(String s)
is quite suitable in this case. 我正在获得像
PT15M51S
这样的ISO8601-String,并且Duration.parse(String s)
非常适合这种情况。
But now I'm struggling how to get the java.sql.Time
to but it into PreparedStatement
with setTime(java.sql.Time time)
to store it in my MySQL-database using JDBC. 但现在我挣扎如何获得
java.sql.Time
到,但它进入PreparedStatement
与setTime(java.sql.Time time)
使用JDBC来将其存储在我的MySQL数据库。
I ended up writing a tapeworm like from org.apache.commons.lang3.time.DurationFormatUtils
: 我最终从
org.apache.commons.lang3.time.DurationFormatUtils
编写了一个Tapeworm:
java.sql.Time.valueOf(DurationFormatUtils.formatDurationHMS(video.getDuration().toMillis())))
And for the next problem: How to get java.time.Duration
from a java.sql.Time
. 对于下一个问题:如何从
java.sql.Time
获取java.time.Duration
。
A java.sql.Time
is not a duration, it is a time within a day (ie the normal 24 hour clock). java.sql.Time
不是持续时间,而是一天中的时间(即正常的24小时制)。 Storing a duration in it is a hack and that hack will break if that duration is longer than 24 hours. 在其中存储持续时间是一个hack,如果该持续时间超过24小时,该hack将中断。 You are better off storing it as the ISO duration string, or in a number datatype (eg double, or maybe numeric) or if your database supports it: in an
interval
. 最好将其存储为ISO持续时间字符串,数字数据类型(例如,双精度或数字)或数据库支持的
interval
:
However if you still want to store the duration in a sql TIME
: The conversion point from java.time
to java.sql.Time
is java.time.LocalTime
using java.sql.Time.valueOf(LocalTime)
. 但是,如果您仍想将持续时间存储在sql
TIME
:使用java.sql.Time.valueOf(LocalTime)
java.time.LocalTime
java.sql.Time.valueOf(LocalTime)
从java.time
到java.sql.Time
的转换点是java.time.LocalTime
。 So to convert from a Duration
to java.sql.Time
you can do: 因此,要从
Duration
转换为java.sql.Time
您可以执行以下操作:
Duration duration = ..;
LocalTime localTime = LocalTime.MIDNIGHT.plus(duration);
java.sql.Time sqlTime = java.sql.Time.valueOf(localTime);
The conversion back would be: 转换回将是:
java.sql.Time sqlTime = ..;
LocalTime localTime = sqlTime.toLocalTime();
Duration duration = Duration.between(LocalTime.MIDNIGHT, localTime);
Be aware that a java.sql.Time
might only have precision in seconds. 请注意,
java.sql.Time
可能只具有几秒钟的精度。 With a JDBC 4.2 compliant driver conversion to java.sql.Time
is not necessary because storing a java.time.LocalTime
is supported directly using setObject(1, <your LocalTime>)
and getObject(1, java.time.LocalTime.class)
. 用JDBC 4.2兼容的驱动程序转换到
java.sql.Time
是没有必要的,因为存储java.time.LocalTime
使用直接支撑setObject(1, <your LocalTime>)
和getObject(1, java.time.LocalTime.class)
。
Is the database structure fixed? 数据库结构是否固定? I think
TIME
or TIMESTAMP
is probably not the best data type for duration. 我认为
TIME
或TIMESTAMP
可能不是持续时间的最佳数据类型。 I would change the column type to BIGINT
(aka Long
) and convert the duration to milliseconds (or nanoseconds depending on your needs) with Duration.toMillis()
. 我将列类型更改为
BIGINT
(aka Long
),并使用Duration.toMillis()
将持续时间转换为毫秒(或纳秒,具体取决于您的需求Duration.toMillis()
。
If this is not an option, you could use a similar logic and represent the duration as offset from a certain timestamp, such as 1970-01-01T00:00:00.000Z
with Duration.addTo(referenceDate)
or java.sql.Time(durationInMillis)
. 如果这不是一个选择,则可以使用类似的逻辑,并将持续时间表示为相对于某个时间戳的偏移量,例如
1970-01-01T00:00:00.000Z
使用Duration.addTo(referenceDate)
或java.sql.Time(durationInMillis)
。 To obtain an instance of Duration
again you will need to use Duration.ofMillis(sqlTime.getTime())
. 要再次获取
Duration
的实例,您将需要使用Duration.ofMillis(sqlTime.getTime())
。
These are basically the options you have: 这些基本上是您可以选择的选项:
Using BIGINT
as column type (preferred solution): 使用
BIGINT
作为列类型(首选解决方案):
// from java.time.Duration to java.lang.Long
{
final Duration duration = ...
final PreparedStatement pStmnt = con.prepareStatement("...");
pStmnt.setLong(n, duration.toMillis());
}
// from java.lang.Long to java.time.Duration
{
final PreparedStatement pStmnt = con.prepareStatement("...");
final ResultSet resultSet = pStmnt.getResultSet();
while (resultSet.next()) {
final Long durationInMillis = resultSet.getLong(n);
final Duration duration = Duration.ofMillis(durationInMillis);
...
}
}
Using TIME
or TIMESTAMP
as column type. 使用
TIME
或TIMESTAMP
作为列类型。 You can replace java.sql.Time
with java.sql.Timestamp
in the below code depending on your actual column type: 您可以根据实际的列类型在以下代码中用
java.sql.Timestamp
替换java.sql.Time
:
// from java.time.Duration to java.sql.Time(stamp)
{
final Duration duration = ...
final Time time = new Time(duration.toMillis());
final PreparedStatement pStmnt = con.prepareStatement("...");
pStmnt.setTime(n, time);
}
// from java.sql.Time(stamp) to java.time.Duration
{
final PreparedStatement pStmnt = con.prepareStatement("...");
final ResultSet resultSet = pStmnt.getResultSet();
while (resultSet.next()) {
final Time time = resultSet.getTime(n);
final Duration duration = Duration.ofMillis(time.getTime());
...
}
}
According to MySQL's documentation the TIME
type supports ranges from -838:59:59
to 838:59:59
(see here ). 根据MySQL的文档,
TIME
类型支持的范围是-838:59:59
到838:59:59
(请参阅此处 )。 But by default none of the types TIME
, DATE
or TIMESTAMP
support fractional seconds unless the desired precision has been specified at creation time of the database columns (see here ). 但是默认情况下,除非在数据库列的创建时指定了所需的精度,否则
TIME
, DATE
或TIMESTAMP
类型都不支持小数秒(请参阅此处 )。 That is to store milliseconds in a TIME
column, the table needs to be created like this: 也就是说要在
TIME
列中存储毫秒,需要像这样创建表:
CREATE TABLE t1 (t TIME(3));
Update: 更新:
TIME
TIME
的受支持的最小最大值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.