Java SpringJDBC持久分区DateTime

Java SpringJDBC持久分区DateTime,java,spring,jdbc,Java,Spring,Jdbc,我正在使用一个web门户的时钟输入/输出功能,该门户可以被不同时区的终端访问 我使用ZonedDateTime来计算给定打卡输入/输出记录的日期时间 // Get store timezone ZoneId storeTimeZone = this.storeService.getStoreZoneId(storeNum); // Get current store time to use for punch in / out timestamp ZonedDateTime currentSt

我正在使用一个web门户的时钟输入/输出功能,该门户可以被不同时区的终端访问

我使用ZonedDateTime来计算给定打卡输入/输出记录的日期时间

// Get store timezone
ZoneId storeTimeZone = this.storeService.getStoreZoneId(storeNum);

// Get current store time to use for punch in / out timestamp
ZonedDateTime currentStoreTime = ZonedDateTime.ofInstant(Instant.now(), storeTimeZone);
当我要将数据持久化到Oracle 11g时,我无法持久化ZoneDateTime对象。JDBC驱动程序可能不支持。这是一个企业环境,所以数据库和驱动程序不会改变

当我构建MapSqlParamSource以传递到NamedParameterJdbcTemplate时,我必须将其转换为java.sql.Timestamp,但随后我会丢失区域数据并存储服务器所在时区的时间戳,需求要求它必须存储在数据库中的存储时间中,该数据库只是Oracle时间戳列

params.addValue("clockInTimestamp", Timestamp.from(prevRecord.getTimeEntryTimestamp().toInstant()), Types.TIMESTAMP);

有没有办法完成这个持久化的ZonedDateTime?Sprint启动项目将自动加载
JSR310JPA转换器
,但这将只处理
LocalDateTime
类型的转换,而不是
ZonedDateTime
。如果您不使用Spring Boot,您可以自己加载这些额外的转换器


您可能希望调整应用程序以使用数据库交互级别的应用程序,只需将保存的所有内容强制放在一个标准时区中,这样您就可以轻松地转换为
ZoneDateTime
,如果出于用户显示目的需要。

我可以通过将ZoneDateTime转换为Instant,然后使用时区偏移量手动计算时间戳

示例代码如下:

ZonedDateTime timeEntry = ZonedDateTime.now();

ZoneOffset storeOffset = timeEntry.getOffset();
ZoneOffset serverOffset = ZonedDateTime.now().getOffset();

int secondsOffset = storeOffset.getTotalSeconds() - serverOffset.getTotalSeconds();

Instant entryTimestamp = timeEntry.toInstant().plusSeconds(secondsOffset);

Timestamp ts = Timestamp.from(entryTimestamp);
然后我将java.sql.Timestamp持久化到数据库中


我确信这不是最干净或最好的解决方案,但由于无法更改数据库、驱动程序或其他工作方式,它似乎做得很好。

我成功地为MySQL解决了这个问题,因此它可能适用于其他人。我在将参数添加到
MapSqlParameterSource

ZonedDateTime zdt = ZonedDateTime.now();
LocalDateTime ldt = LocalDateTime.ofInstant(zdt.toInstant(), ZoneId.systemDefault());

MapSqlParameterSource parameters = new MapSqlParameterSource();
parameters.addValue("datetime", ldt, Types.JAVA_OBJECT);

忘记了Spring、JDBC等的细节——听起来你想在一个只能存储瞬间的字段中存储“瞬间+时区”。。。所以这不会比“我想在一个4字节的字段中存储32字节的数据”更有效。我建议您确定要存储哪些信息以及以何种方式存储,然后确定如何实现。请注意,JDBC没有定义对
ZonedDateTime
的支持,只定义对
OffsetDateTime
OffsetTime
LocalDate
,的支持,
LocalDateTime
LocalDate
jsr310jpa转换器
是JPA的东西。看起来这里只使用了纯spring jdbc。这是正确的答案,但您不需要
类型。JAVA\u对象