-
Notifications
You must be signed in to change notification settings - Fork 356
Timezone handling #986
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Is it possible, that you get mislead by the If I save an entity with the instant as described, and load the timestamp using a
I get the following output:
I'm in CET, which is one hour ahead of UTC right now. |
I've tested against JPA and it seems it also results in spring data jdbc result - 2021-01-01 01:00:00.0000000. |
The original source of my issue is located here in this test - https://github.com/infobip/infobip-spring-data-querydsl/blob/issue-31-fix/infobip-spring-data-jdbc-querydsl/src/test/java/com/infobip/spring/data/jdbc/QuerydslJdbcRepositoryTest.java#L198-L212 When I query the database with following tsql: SELECT DATEDIFF(SECOND, '19700101', CreatedAt) FROM Person I get 1609462800 as result for Spring Data which https://www.epochconverter.com/ tells me is GMT: Friday, January 1, 2021 1:00:00 or Your time zone: Friday, January 1, 2021 2:00:00 which doesn't seem right. |
I think we got bitten by the JDBC API which seems to have a rather creative interpretation of dates. This Stackoverflow answer tipped me of. It talks about variants of So here is what seems to happen. I assume
This intern probably delegates to
Now the interesting part is of course the statement:
But JDBC (or at least the driver of MS SQL Server) seems to do the following:
And it odes the reverse when loading the timestamp from the database again. At least that is my current interpretation of what I'm seeing and reading. |
I've debugged the test and Spring Data JDBC invokes setTimestamp method on PreparedStatement with java.sql.Timestamp and my understanding is that it's game over by that point. |
While I think the JDBC API or SQL Servers driver implementation is using But we can't really switch to an approach where we provide a |
I agree and to clarify - I wanted to identify root of the issue before proceeding. I'm trying to solve this issue (infobip/infobip-spring-data-querydsl#31) because I've run out of easy options to prevent users from stumbling on this issue - that is time handling difference between Spring Data JDBC and Querydsl. I believe the following "hack" would work but I have yet to test it: <O> List<O> queryMany(SQLQuery<O> query) {
@SuppressWarnings("unchecked")
RowMapper<O> rowMapper = (RowMapper<O>) new EntityRowMapper<>(entity, converter);
RowMapperResultSetExtractor<O> rowMapperResultSetExtractor = new RowMapperResultSetExtractor<>(rowMapper);
List<O> result = query(query, rowMapperResultSetExtractor);
if (Objects.isNull(result)) {
return Collections.emptyList();
}
return result;
} |
After further investigation the "hack" I mentioned above doesn't work and mapping SQLQuery projection expression to a custom row mapper or something similar doesn't seem like something that would scale or make sense really. It'd be great if Spring Data JDBC provided some sort of override mechanism. |
We'll probably implement some way to configure this. In the meantime you should be able to register custom converters for the conversion from and to |
@Demo-80 please do not hijack only vaguely related tickets. Also, your question seems to be a usage question. Please ask those over on Stackoverflow. If you think you found a bug or want to share an idea for a feature or improvement feel free to create a ticket. |
|
For an Instant defined as:
when using Spring Data JDBC repository save method I'd expect the end result in MSSQL database column of type datetime2 to be of value: 2021-01-01 00:00:00.0000000 but it contains value 2021-01-01 01:00:00.0000000 suggesting that Spring Data JDBC uses my machine timezone when converting Instant.
Is this behavior documented anywhere and can it be configured somehow? I'd like my application to always use UTC unless a type with explicit timezone and/or offset is used.
The text was updated successfully, but these errors were encountered: