Vert.x PostgreSQL Client 4.x: Standardizing TIMESTAMPTZ to UTC or Regional Zones
0 reputation · 25 Jun 2020, 11:49 UTC
0 reputation · 25 Jun 2020, 11:49 UTC
The client maps PostgreSQL TIMESTAMPTZ to java.time.OffsetDateTime and TIMESTAMP to java.time.LocalDateTime. The offset is preserved, but the JVM default zone or the database session time zone can alter the perceived value when read back or serialized to JSON.
Should the application store all instants as UTC (TIMESTAMPTZ/OffsetDateTime) and convert to regional zones only for display, or should it persist wall‑clock times with an explicit zone column? This choice impacts how tests, deployments, and JSON payloads behave across regions.
Given that Vert.x’s default JSON handling requires explicit Jackson configuration, and that session time zones can vary by driver version, the correct approach is unclear.
What are the best practices for:
OffsetDateTime across environments?Store all instants as UTC by mapping PostgreSQL TIMESTAMPTZ to java.time.OffsetDateTime with an offset of zero (+00:00). Configure the Vert.x PostgreSQL client to force the database session time zone to UTC, and use a single Jackson ObjectMapper with the JavaTimeModule for JSON serialization.
If the session time zone is left to the JVM default or varies per connection, the same TIMESTAMPTZ value may be read back with a different offset, causing shifts in tests, deployments, and JSON payloads. Setting the session explicitly removes that variability.
When creating the PgPool, add an init script or connection property that sets the session time zone to UTC, e.g.:
PgPoolOptions opts = new PgPoolOptions()
.setPort(5432)
.setHost("localhost")
.setDatabase("mydb")
.setUser("user")
.setPassword("secret")
.addInitScript("SET TIME ZONE UTC;"); // or use connection property "TIMEZONE=UTC"
PgPool client = PgPool.pool(vertx, opts);
Verify the setting (optional diagnostic): after obtaining a connection, run SHOW TIMEZONE; and confirm it returns UTC. If you are using a Vert.x PostgreSQL client version older than 4.2.0, please confirm your version, as earlier releases may mis-map TIMESTAMPTZ to LocalDateTime.
Configure Jackson once for the whole application:
ObjectMapper mapper = new ObjectMapper()
.registerModule(new JavaTimeModule()) // handles OffsetDateTime, Instant, etc.
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // ISO‑8601 strings
Use this mapper in all Vert.x verticles and HTTP endpoints (e.g., via a shared utility or dependency injection).
When persisting, store OffsetDateTime directly; the driver will send it as a TIMESTAMPTZ with UTC offset.
For display, convert at the view layer: ZonedDateTime zdt = offsetDateTime.atZoneSameInstant(ZoneId.of("America/New_York")); Never persist the converted value.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.