A scheduled report runs at 3 AM instead of 8 AM. An API returns a timestamp that's five hours off. A cron job that worked all year starts firing at the wrong time after the clocks change. A user in Tokyo sees "yesterday's" date on an event that hasn't happened yet. These are all timezone bugs — and they're among the most disorienting issues in software because the code looks correct right up until a clock somewhere disagrees with your assumptions.
This guide breaks down how timezone problems happen, how to reason through them systematically, and how the Timezone Converter on DevToolShack fits into the debugging workflow.
The Root Cause: Ambiguous Times
Most timezone bugs stem from storing or transmitting a time without specifying what timezone it's in. "2026-07-20 08:00:00" means nothing without a timezone. Is that UTC? US Eastern? Server local time? The bug typically surfaces when the system that writes the time and the system that reads it disagree on the answer — and they're often running in different timezones.
The fix is always the same: use unambiguous formats. UTC is the standard. ISO 8601 with a timezone offset (2026-07-20T08:00:00-05:00) or with a Z suffix (2026-07-20T13:00:00Z) is never ambiguous. Unix timestamps in seconds since epoch are also timezone-neutral. Any stored time that doesn't include a timezone reference is a bug waiting to happen.
The Three Places Timezone Bugs Hide
1. The Database
MySQL's DATETIME type stores the literal value you give it with no timezone information. If you insert 2026-07-20 08:00:00 from a US Eastern server and then read it from a UTC server, you get back the same string — but it now means 8 AM UTC, not 8 AM Eastern. This is the source of countless "timestamps are off by N hours" bugs.
PostgreSQL's TIMESTAMP WITH TIME ZONE (also written TIMESTAMPTZ) converts the stored value to UTC internally and converts it back to the session timezone on retrieval. If your session timezone is set consistently, this is safer — but it introduces a different class of bugs if different connections use different session timezones.
The defensive practice: always store UTC in the database. Do timezone conversion at the application layer, as close to the user as possible.
2. Cron Jobs
Cron runs in the server's local timezone unless you explicitly configure it otherwise. A job scheduled for 0 8 * * * runs at 8 AM server time. If the server is in UTC and you're in UTC-5, that's 3 AM your time. When daylight saving kicks in and your offset changes to UTC-4, the job appears to shift — except it hasn't: it's still 8 AM UTC, but now that's 4 AM your time.
The fix for cron is to set the CRON_TZ environment variable or the TZ variable in the crontab to a named timezone rather than relying on system defaults. For building and validating cron expressions, the Cron Builder on DevToolShack shows you exactly when each expression will fire. Pair it with the Timezone Converter to verify the UTC time maps to the local time you intend. For a full cron syntax reference, see How to Read and Write Cron Job Expressions (With Examples).
3. APIs and Third-Party Services
External APIs are wildly inconsistent. Some return UTC with a Z suffix; some return Unix timestamps; some return local time with an offset; some return local time with no offset at all (the worst case). Before writing any date-parsing code against an API, check the documentation for the exact format — and if the documentation is unclear, look at actual response payloads.
When an API returns a timestamp that seems wrong, the Timezone Converter is the fastest way to check what a given time looks like across multiple zones simultaneously. Paste in the timestamp, select the source timezone, and compare. Usually the "wrong" time is just the right time in the wrong zone.
Daylight Saving Time: The Gift That Keeps Giving
DST is the reason named timezones like America/New_York are safer than fixed offsets like UTC-5. The offset for New York is UTC-5 in winter and UTC-4 in summer. If you hardcode UTC-5, your scheduled events shift by an hour twice a year. Named IANA timezone identifiers (the America/New_York format) know the DST rules and apply them automatically.
DST transitions also create genuinely ambiguous times. When clocks fall back from 2:00 AM to 1:00 AM, there are two 1:30 AMs. A cron job scheduled for 1:30 AM may run twice. When clocks spring forward, 2:30 AM doesn't exist — a job scheduled for that time may be skipped or delayed. These edge cases are why AWS EventBridge, GitHub Actions, and other cloud schedulers recommend UTC for all cron expressions.
Debugging a Timezone Bug Step by Step
When you encounter a time that appears wrong, work through these questions:
- What timezone was the time generated in? Check the server's timezone (
datein Linux,SELECT @@global.time_zonein MySQL). - What timezone does the storage layer assume? Is it UTC? Local? Unspecified?
- What timezone is the reader in? The client browser? Another server? A reporting tool?
- Does the stored value include timezone information? If not, that's the bug.
- Is DST involved? Check whether the offset has changed since the value was written.
The Timezone Converter helps with steps 1, 3, and 5 by showing the same moment in multiple zones at once. The Unix Timestamp Converter helps with step 4 — converting a raw timestamp to a human-readable UTC time removes any ambiguity about what moment is actually stored. For the relationship between Unix timestamps and timezones, see Unix Timestamps Explained: What They Are and How to Convert Them.
Best Practices That Prevent the Bug in the First Place
- Store everything in UTC. Convert to local time only when displaying to a user.
- Use ISO 8601 with timezone offsets for any time transmitted between systems.
- Use IANA timezone names (not fixed offsets) wherever you configure a timezone.
- Set server and database timezones explicitly rather than relying on defaults — defaults change across environments.
- Schedule cron jobs in UTC when the scheduler supports it.
- Use
Intl.DateTimeFormatorTemporal.ZonedDateTimein JavaScript for display rather than constructing timezone-adjusted strings manually.
Using the Timezone Converter for Scheduling Across Teams
Beyond debugging, the Timezone Converter is useful for scheduling meetings, API maintenance windows, or deployment events across teams in different locations. Enter a UTC time and see it in New York, London, and Tokyo simultaneously — much faster than calculating offsets by hand, and it accounts for DST automatically.