Java SpringJDBC持久分区DateTime
我正在使用一个web门户的时钟输入/输出功能,该门户可以被不同时区的终端访问 我使用ZonedDateTime来计算给定打卡输入/输出记录的日期时间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
// 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对象