我正在尝试将日期值插入数据库,如下所示。
UPDATE table_name SET date_field = ?
WHERE ROW_ID = ?
这是 DTO。
public class ImportExportProgressDTO {
private Calendar prolongedDate;
}
public void update(ImportExportProgressDTO importExportProgressDTO){
Connection connection = getConnection();
PreparedStatement preparedStatement = con.prepareStatement(queryString);
preparedStatement.setString(parameterIndex++, LocalDateTime.ofInstant(importExportProgressDTO.getProlongedDate().toInstant(), ZoneId.of("Asia/Kolkata")).toString());
preparedStatement.executeUpdate();
}
2024-04-09 11:50:54
—这是有效负载中的值。
0014-10-13T17:44:22
—该值正在插入数据库中。
私人日历延长日期;
永远不要使用有严重缺陷的
java.util.Calendar
类。该类与 Date
类和 java.sql.Timestamp
类一样,都是遗产。这些类几年前就被 JSR 310 中定义的现代 java.time 类取代。
作为与数据库访问一起使用的 DTO,如果表示时刻(时间轴上的特定点),该类型应该是
java.time.OffsetDateTime
。
数据库列的类型应类似于 SQL 标准类型
TIMESTAMP WITH TIME ZONE
。
preparedStatement.setString(parameterIndex++, LocalDateTime.ofInstant(importExportProgressDTO.getProlongedDate().toInstant(), ZoneId.of("亚洲/加尔各答")).toString());
这是一团丑陋的日期时间代码。
本地日期时间
如果您代表时间轴上的一个时刻、一个点,则不应涉及
LocalDateTime
。该类表示带有时间的日期,但缺少时区上下文或相对于 UTC 的偏移量。所以这堂课不能代表一个时刻。此类的对象本质上是不明确的。
本地日期时间.ofInstant
我无法想象调用该方法有意义的场景。
importExportProgressDTO.getProlongedDate()
我假设这个调用返回一个
java.util.Calendar
。但你应该明确地说出来。
如果您无法修复 DTO 以使用
OffsetDateTime
,并且被 Calendar
对象卡住,请立即转换。
要转换,请验证该对象实际上是一个
GregorianCalendar
对象,这很有可能。如果是这样,请转换为 ZonedDateTime
对象。
Calendar calendar = importExportProgressDTO.getProlongedDate();
ZonedDateTime zdt = null ;
if ( calendar instanceof java.util.GregorianCalendar )
{
zdt = ( ( GregorianCalendar ) calendar ).toZonedDateTime() ;
}
else
{
// Handle problem
}
然后转换为
OffsetDateTime
。这是 JDBC 中唯一映射到 TIMESTAMP WITH TIME ZONE
的类。另外两个矩类,Instant
和 ZonedDateTime
,没有这样映射。
OffsetDateTime odt = zdt.toOffsetDateTime() ;
ZoneId.of("亚洲/加尔各答")
无需申请时区。您的原始
Calendar
对象(GregorianCalendar
对象)已包含时区。该区域转移到 ZonedDateTime
对象。