-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
I found some more shady JDK methods (story of my life) #125
Comments
Hi, public static final ThreadLocal<Calendar> UTC_CAL =
ThreadLocal.withInitial(() -> new GregorianCalendar(TimeZone.getTimeZone(ZoneOffset.UTC), Locale.ROOT));
//...
result.getTimestamp(col, UTC_CAL.get()); The threadlocal is needed because the Calendar on its own is not thread safe (urgh). I am not sure if we can easily add those to the general unsafe ones. Mabye add another bundled signature? |
FYI, |
The thread-local I guess the catch is that even if our code currently calls a database where the method is safe, having used JDBC makes future developers think that it will work correctly on another database, so they might happily switch databases without noticing that it's not working correctly. (It took us over 10 years to discover this issue in the first place, in Derby, where we had incorrectly assumed that it was storing timestamps as, well, a timestamp.) And yeah, So you're right, they should burn JDBC to the ground and try again. Maybe next time they'll get it right. In the meantime I currently have all the bad stuff calling through static utility methods, but it seems easy to forget to call those, so I'm thinking I might have to wrap the entire API to discourage doing things the wrong way. :/ |
The worst here is: You fetch a value from the database, it is converted according to local timezone. When you then update it and store it again using a prepared statement it is converted back to a local time. The problem is: If DST changes apply, the whole process is not bidirectional! We figured out that at the time when DST changes apply (one hour in spring and one hour in autums), all your database values break because the conversion database -> long -> database is not returning the same value as before! This is the reason why I tend to always use UTC as timezone for calculations. Yes, JDBC should use LocalDateTime, LocalDate, LocalTime instances from the java.time API. The problem with JDBC is: It's all interfaces, so you cannot change without breaking all drivers out there! |
Many databases (MS SQL Server and Derby confirmed, probably many others as well) store the date/time values in local time with no zone, so for methods which set date values without passing a time zone it's unclear which value you're going to be storing. Often you have to read the documentation for the network protocol to know what the database will use...
But it turns out that all the following methods also have a second overload taking
java.util.Calendar
, which of course allows passing in an explicit time zone, so maybe they should just be added to the list.The text was updated successfully, but these errors were encountered: