MySQL
UTC conversion
timezone
database
SQL query

Can MySQL convert a stored UTC time to local timezone?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Yes, MySQL can convert a stored UTC value into a local time zone, but the exact behavior depends on the column type and whether your server has time zone tables loaded. The most important distinction is between DATETIME, which stores a literal date-time value, and TIMESTAMP, which participates in time zone conversion rules.

Use CONVERT_TZ for Explicit Conversion

If your table stores UTC values and you want a specific local zone in the query result, use CONVERT_TZ:

sql
1SELECT
2    created_at_utc,
3    CONVERT_TZ(created_at_utc, '+00:00', 'America/Toronto') AS created_at_local
4FROM orders;

This works for both DATETIME and TIMESTAMP inputs, but the meaning differs slightly.

  • For DATETIME, MySQL treats the stored value as plain calendar data. You are telling MySQL, "interpret this value as UTC, then convert it."
  • For TIMESTAMP, MySQL already stores the value in UTC internally and converts on input and output using the session time zone.

If you want daylight-saving behavior, prefer a named zone such as 'America/Toronto' instead of a fixed offset like '-05:00'. A fixed offset does not know when summer time begins or ends.

DATETIME Versus TIMESTAMP

This is where many bugs start.

With DATETIME, inserting '2026-03-11 15:00:00' stores exactly that text-like value. MySQL does not know whether it is UTC, local time, or a mistake.

With TIMESTAMP, MySQL converts between the session time zone and UTC automatically:

sql
1SET time_zone = '+00:00';
2
3CREATE TABLE events (
4    id INT PRIMARY KEY AUTO_INCREMENT,
5    happened_at TIMESTAMP NOT NULL
6);
7
8INSERT INTO events (happened_at)
9VALUES ('2026-03-11 15:00:00');

If you later change the session time zone and select the row, the displayed value changes:

sql
SET time_zone = 'America/Toronto';

SELECT happened_at FROM events;

That automatic behavior is convenient, but only if you understand it. Many teams prefer storing UTC in DATETIME and converting explicitly in queries or the application layer because it is easier to reason about.

Named Time Zones Require Time Zone Tables

CONVERT_TZ returns NULL if the time zone arguments are invalid. A common reason is that the MySQL time zone tables were never loaded on the server.

This query is a quick check:

sql
SELECT CONVERT_TZ('2026-03-11 15:00:00', '+00:00', 'America/Toronto');

If it returns NULL, the server may not recognize named zones yet. In that case, fixed offsets still work:

sql
SELECT CONVERT_TZ('2026-03-11 15:00:00', '+00:00', '-05:00');

That is useful as a fallback, but it is not equivalent for daylight-saving transitions.

A Practical Pattern

A common pattern is:

  1. Store all application timestamps in UTC.
  2. Keep the stored value unchanged in the database.
  3. Convert at read time for reports, exports, or user-facing queries.

Example:

sql
1CREATE TABLE messages (
2    id INT PRIMARY KEY AUTO_INCREMENT,
3    sent_at_utc DATETIME NOT NULL
4);
5
6INSERT INTO messages (sent_at_utc)
7VALUES ('2026-03-11 18:30:00');
8
9SELECT
10    sent_at_utc,
11    CONVERT_TZ(sent_at_utc, '+00:00', 'Europe/Berlin') AS sent_at_berlin
12FROM messages;

This keeps the source of truth stable while still letting each user or report request its own local representation.

Common Pitfalls

  • Mixing DATETIME and TIMESTAMP without understanding that TIMESTAMP is session-time-zone aware.
  • Using fixed offsets when you actually need daylight-saving-aware named zones.
  • Forgetting to load MySQL time zone tables, which makes named-zone conversion return NULL.
  • Storing local time and later trying to guess which zone it originally belonged to.
  • Converting in both the application and the SQL query, which shifts the value twice.

Summary

  • MySQL can convert stored UTC values to local time zones with CONVERT_TZ.
  • 'DATETIME stores literal values, while TIMESTAMP participates in automatic session-based conversion.'
  • Named zones such as 'America/Toronto' are better than fixed offsets when daylight saving matters.
  • If named-zone conversion returns NULL, check whether the MySQL time zone tables are loaded.
  • The safest long-term pattern is usually to store UTC and convert only at the edges.

Course illustration
Course illustration

All Rights Reserved.