Dev.to · 3 min read

SYSDATE Is Hours Off After the Move to the Cloud. Nothing Errors.

SYSDATE Is Hours Off After the Move to the Cloud. Nothing Errors.

The migration went well. The database moved from the server room to the cloud over the weekend, the row counts matched, the application connected, and nobody saw an error. On Monday afternoon someone asks why the "today's orders" report has stopped showing the evening's orders. On Tuesday the nightly export picks up rows from the wrong day. The audit log and the application log disagree by five hours. Nothing is broken, and that's why it takes days to find. Every SYSDATE in the database now returns UTC, and every column with DEFAULT SYSDATE is filling with UTC times, in the same column as years of local times. SYSDATE doesn't come from the database. It comes from the operating system's clock and time zone, as the database server process sees them. The on-prem server ran in local time. The new host, like most cloud servers and nearly every container image, runs in UTC. This post shows exactly what moves, what doesn't, the fixes that look right and change nothing, and the two that work. All of it is reproduced in a lab. What moves, and what doesn't Oracle has several "now" functions, and they don't all read the same clock: function where its time zone comes from SYSDATE, SYSTIMESTAMP the server process's OS time zone (TZ) CURRENT_DATE, CURRENT_TIMESTAMP, LOCALTIMESTAMP the session time zone, which the client sets DBTIMEZONE a database setting, used for TIMESTAMP WITH LOCAL TIME ZONE columns The first row is the one that matters, because it's what applications use: DEFAULT SYSDATE on a column, WHERE order_date >= TRUNC(SYSDATE) in a report, SYSDATE - 1 in a purge job. When the database moves to a host in another time zone, all of it moves with the host. An order placed at 8pm in Chicago is stored as 1am the next day (2am in winter). Every report that groups by TRUNC(order_date) puts the evening's orders on tomorrow. Prove it The lab runs Oracle Database Free in a container and "moves" it the only way that matters for SYSDATE: it starts the instance with TZ=America/Chicago (the on-prem server), then restarts the same instance in UTC (the cloud host). An application schema has an ORDERS table with ORDER_DATE DATE DEFAULT SYSDATE. Before and after the move, it checks what the application's session and a scheduler job see, and places one order: on-prem (Chicago) moved (UTC) app session, SYSDATE 07:28 12:28 SYSDATE offset from UTC -5 h 0 h scheduler job, SYSDATE offset -5 h 0 h order 1 on-prem 2026-10-31 07:28 order 2 in the cloud 2026-10-31 12:28

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More Startup & VC News