I prefer all times to be in UTC, except for when they are displayed. At the last moment, they can be converted to a local time for display only.
I've always stored UNIX timestamps (seconds since epoch) in MySQL before, in an integer field. I'm working with someone else's database schema that I cannot change which uses a DATETIME
that stores a raw time without even an offset.
How can I retrieve and send time objects with the database in UTC, so the database is doing absolutely no conversions whatsoever?
Although written for PostgreSQL, I've tried to follow the excellent answers by Basil Bourque on the questions below. I use Instant
everywhere, except as he shows I use an OffsetDateTime
when interacting with JDBC, because it's the only modern moment class guaranteed to be supported by JDBC 4.2.
- How to convert UTC date to UTC OffsetDateTime in java 8?
- Issue in saving current date with UTC time in sql server
- and How to save correct date time with timezone when using jdbc
I'm using MySQL Connector/J driver version 8.0.27, and I am connecting with &preserveInstants=false&connectionTimeZone=UTC
.
Let's look at a DATETIME
in the database stored as "2022-01-14 11:00:00" which is understood to be UTC.
resultSet.getString(columnName); // "2022-01-14 11:00:00"
resultSet.getObject(columnName, OffsetDateTime.class).toString() // "2022-01-14T11:00-04:00"
resultSet.getObject(columnName, OffsetDateTime.class).toInstant().toString() // "2022-01-14T15:00:00Z"
When it's creating the OffsetDateTime
, it's assigning either the system or server (same machine) offset of "-04:00" and messing everything up. I thought my connection options of &preserveInstants=false&connectionTimeZone=UTC
should have stopped that.
I know I could immediately set the offset to "+00:00" afterward with .withOffsetSameLocal(ZoneOffset.UTC).toInstant()
, but how do I avoid doing that and have it directly create an OffsetDateTime
that is in UTC?