convert_tz returns null
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
CONVERT_TZ() returns NULL in MySQL when the timezone tables are not populated. MySQL needs timezone data loaded into the mysql.time_zone* system tables to convert between named timezones like 'America/New_York'. By default, these tables are empty after installation. The fix is to run mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql on Linux, or download timezone data from MySQL's website for Windows. After loading, CONVERT_TZ('2025-01-01 12:00:00', 'UTC', 'America/New_York') works correctly.
The Problem
If CONVERT_TZ returns NULL with named timezones but works with offset notation (+00:00), the timezone tables are empty.
Diagnosing the Issue
MySQL stores timezone data in five system tables: time_zone, time_zone_name, time_zone_transition, time_zone_transition_type, and time_zone_leap_second. All must be populated for named timezone conversion to work.
Fix: Load Timezone Data (Linux/macOS)
The mysql_tzinfo_to_sql utility reads the OS timezone files and generates SQL statements to populate MySQL's timezone tables.
Fix: Load Timezone Data (Windows)
Windows does not ship POSIX timezone files. Download the prebuilt SQL file from MySQL's website and import it manually.
Fix: Docker Containers
Docker MySQL containers start with empty timezone tables. Add an init script to load them on first startup.
Workaround: Use UTC Offsets
UTC offsets always work regardless of timezone table state. However, they do not handle daylight saving time transitions — you must manually use the correct offset for each date.
Using CONVERT_TZ Correctly
Updating Timezone Data
Timezone rules change periodically (countries modify DST dates). After updating the OS timezone data, re-run mysql_tzinfo_to_sql to keep MySQL in sync.
Common Pitfalls
- Assuming timezone tables are populated by default: MySQL installation does NOT load timezone data automatically. The
mysql.time_zone*tables are empty until you explicitly runmysql_tzinfo_to_sql. This catches nearly every new MySQL setup. - Using offsets instead of named timezones for DST-aware conversion:
CONVERT_TZ(dt, '+00:00', '-05:00')does not handle daylight saving time.America/New_Yorkis UTC-5 in winter and UTC-4 in summer. Only named timezones handle DST transitions automatically. - Not updating timezone data after OS updates: When a country changes its DST rules, the OS timezone files are updated via package managers, but MySQL's tables remain stale. Re-run
mysql_tzinfo_to_sqlaftertzdataupdates. - Missing permissions to write to mysql database: Loading timezone data requires write access to the
mysqlsystem database. Regular users typically cannot run the load command — use therootMySQL user or a user withINSERTprivileges onmysql.*. - Docker containers losing timezone data on restart: If MySQL data is not persisted via a volume, timezone data loaded during runtime is lost when the container restarts. Use an init script in
/docker-entrypoint-initdb.d/or a custom Dockerfile to load timezone data during image build.
Summary
CONVERT_TZ()returnsNULLwhen MySQL's timezone tables are empty (the default after installation)- Run
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysqlto load timezone data on Linux/macOS - On Windows, download the timezone SQL file from MySQL's website and import it
- UTC offset notation (
+00:00,-05:00) always works but does not handle daylight saving time - Named timezones (
America/New_York) automatically handle DST transitions - Re-run the timezone loader after OS
tzdataupdates to keep MySQL's data current

