Timezone differences causing test failures
April 30, 2026 · View on GitHub
Playbook ID: timezone-diff
Category: test
Severity: medium
Tags: timezone, utc, time, test, date, dst
What this failure means
A test that compares date or time values fails because the CI runner operates
in a different timezone than the development machine. Code that implicitly
calls datetime.now(), new Date(), or similar without a timezone argument
returns local time, which differs across environments.
Common log signals
expected.*UTC
got.*local time
timezone.*mismatch
assertion.*datetime
Expected.*+0000
received.*+0
wrong timezone
AssertionError.*datetime
Diagnosis
CI runners commonly default to UTC or a cloud region timezone. Developer machines use local timezones. Tests that construct expected values with date helpers or hardcode timestamps without UTC anchoring will produce different results on each environment.
Common patterns that cause timezone failures:
datetime.now()ornew Date()withouttimezone.utc/Zsuffix- Date formatting that produces locale-dependent output
- Database timestamps stored and retrieved without explicit timezone handling
- Assertions comparing
strftimeoutput that includes timezone offset
Check the runner timezone:
date
echo $TZ
timedatectl show --property=Timezone --value # Linux systemd
Fix steps
-
Force the CI environment to UTC:
# GitHub Actions env: TZ: UTC # GitLab CI variables: TZ: UTC -
In application code, always use UTC-aware datetime objects and convert to local time only at the presentation layer:
# Python — always UTC from datetime import datetime, timezone now = datetime.now(tz=timezone.utc)// JavaScript — use ISO strings or UTC methods const now = new Date().toISOString(); // "2025-01-01T12:00:00.000Z" const timestamp = Date.UTC(2025, 0, 1, 12, 0, 0); // explicit UTC epoch -
In tests, freeze or mock the clock with a fixed UTC time rather than calling the real system clock:
# Python with freezegun from freezegun import freeze_time @freeze_time("2025-01-01 12:00:00") def test_something(): ... # pytest-mock mocker.patch("mymodule.datetime").now.return_value = fixed_utc_dt// Jest jest.useFakeTimers().setSystemTime(new Date("2025-01-01T12:00:00Z")); -
Store and compare all database timestamps in UTC; use
TIMESTAMPTZin PostgreSQL and UTC-mode drivers in MySQL. -
If tests must exercise timezone conversions, parameterize the timezone explicitly rather than relying on
TZenvironment state.
Validation
- Set
TZ=UTClocally and re-run the failing tests to reproduce them. - After applying fixes, run the suite with several different
TZvalues:TZ=America/New_York,TZ=Asia/Kolkata,TZ=Australia/Sydney. - Confirm all assertions pass regardless of system timezone.
Likely files to inspect
(Not specified.)
Run Faultline
faultline analyze build.log
faultline explain timezone-diff
faultline workflow build.log --json --mode agent
Search phrases this page answers
- Timezone differences causing test failures
- Test: timezone differences causing test failures
- AssertionError.*datetime
- faultline explain timezone-diff
Generated from playbooks/bundled/log/test/timezone-diff.yaml. Do not edit directly — run make docs-generate.