Store ISO 8601 Offsets Correctly in MySQL

A MySQL TIMESTAMP stores an instant in UTC and converts it for the current session when read. From MySQL 8.0.19, an input value can include a numeric offset, but MySQL does not preserve that original offset after conversion.

Last updated: November 7, 2026.

SET time_zone = '+00:00';

CREATE TABLE event_log (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    occurred_at TIMESTAMP(6) NOT NULL,
    source_offset VARCHAR(6) NULL
);

INSERT INTO event_log (occurred_at, source_offset)
VALUES ('2026-11-07 09:30:00-05:00', '-05:00');

SELECT occurred_at, source_offset FROM event_log;

The stored instant is 14:30 UTC. The separate offset column is optional and is needed only when the original civil-time context matters; it is not required for sorting or comparing instants.

Choose TIMESTAMP or DATETIME deliberately

MySQL’s date and time literal reference allows an offset on TIMESTAMP and DATETIME inputs. The offset must be attached to the time with no intervening space. A named zone such as America/New_York cannot be placed directly in the literal.

Use TIMESTAMP for a point on the timeline. MySQL converts it between the session time zone and UTC. Use DATETIME for a wall-clock value that should remain visually unchanged, such as a recurring local opening time. Do not assume a DATETIME represents an instant unless the application stores its zone separately.

Make the session time zone observable

Run SELECT @@SESSION.time_zone, @@GLOBAL.time_zone through the same connection pool as the application. Set the session zone explicitly on every new connection instead of relying on the server host’s operating-system setting. For instant-based systems, UTC is usually the simplest choice.

Use a parameterized statement and a driver type that represents an instant or offset-aware date-time. MySQL’s Connector/J time-instant guide explains how driver and session settings affect preservation. Test both sides of a daylight-saving transition and compare Unix timestamps, not only formatted strings. If the original IANA zone controls later business rules, store that zone separately because a numeric offset has no future DST rules.

See storing UTC and displaying local time, checking MySQL configuration, and finding values before specific dates.

Related Web Cheat Sheet guides

Sergey Kornilov

Sergey Kornilov