Coding Agents & Terminal · recorded 2026-08-31 · applies to 1 tool(s) ✓ Verified

Problem: container time is 8 hours off (date shows UTC) / Chinese text garbled (UnicodeEncodeError) —— Trove problem library

Verified 2026-08-31container time is 8h off / Chinese garbled — use -e TZ=Asia/Shanghai (TZ=UTC-8 for images without tzdata, sign inverted); fix locale for mojibake.

Quick fix

# Timezone: works directly on Debian-family/python images; use POSIX form on tzdata-less images
docker run -e TZ=Asia/Shanghai your-image date          # when the image ships zoneinfo
docker run -e TZ=UTC-8 your-image date                  # no tzdata (UTC-8 = UTC+8, inverted sign)

# Garbled text: force UTF-8 output inside the container
docker run -e PYTHONUTF8=1 -e PYTHONIOENCODING=utf-8 your-python-image ...
# Same in compose
services:
  app:
    image: your-image
    environment:
      - TZ=Asia/Shanghai
      - PYTHONUTF8=1
      - PYTHONIOENCODING=utf-8

What you will run into

Inside the container, date shows UTC while the host is 8 hours ahead; you added -e TZ=Asia/Shanghai to compose/docker run exactly like the tutorial says, restarted, and it is still UTC.

Or your program prints Chinese and dies with UnicodeEncodeError: 'ascii' codec can't encode characters, and Chinese in logs comes out as mojibake/question marks.

Containers default to UTC and the C locale, and slim base images often have no timezone data at all — these two are classic container-deployment openers.

Why this happens

Docker images are based on Linux defaults: timezone = UTC, locale = C. date reads /etc/localtime (or TZ env var + zoneinfo), not the host timezone — containers do not inherit the host timezone.

TZ works in two layers: the TZ env var only tells libc "which zone to look up in zoneinfo".

If the image has no /usr/share/zoneinfo/ (reproduced: the alpine base image does not even have that directory), TZ=Asia/Shanghai silently does nothing and stays UTC — this is the #1 reason "TZ is set but useless".

Two workarounds: ① install tzdata (alpine: apk add tzdata; Debian-family images usually ship it, so -e TZ=Asia/Shanghai just works); ② a POSIX TZ string that needs no zoneinfo (-e TZ=UTC-8 = UTC+8, sign is inverted vs intuition;

reproduced: shows 23:09 matching host CST).

Garbled Chinese also splits into two layers: the program inside the container outputting in ASCII/system encoding (Python in a C locale auto-enables UTF-8 — PEP 540 — and prints Chinese fine, reproduced;

but forcing PYTHONIOENCODING=ascii immediately gives UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128), reproduced verbatim);

and the viewing terminal mis-decoding (container emits UTF-8 bytes, a Windows console decodes them as GBK → mojibake, unrelated to the container).

Deterministic takeaway: TZ not working → docker run --rm <image> ls /usr/share/zoneinfo to check for timezone data; UnicodeEncodeError → check env vars for PYTHONIOENCODING/LANG pinning the encoding.

Step by step

1. Confirm where the time is wrong — Must do

docker run --rm alpine date          # UTC = not effective
docker run --rm alpine ls /usr/share/zoneinfo   # No such file = image has no tzdata

2. Pick the fix by image family — By diagnosis

  • Debian family (ubuntu/debian/python:slim etc.): ships zoneinfo; -e TZ=Asia/Shanghai just works;
  • Alpine family: apk add --no-cache tzdata in the Dockerfile first, then -e TZ=Asia/Shanghai; or skip it with -e TZ=UTC-8 (POSIX, inverted sign);
  • Existing container: changing env vars requires rebuilding the container (docker compose up -d --force-recreate or a fresh docker run); docker restart keeps the env from creation time, so changes do not apply.

3. Debug garbled Chinese — By diagnosis

# Confirm the real stdout encoding inside the container
docker run --rm your-python-image python3 -c "import sys; print(sys.stdout.encoding)"
# utf-8 = fine; ascii = pinned by an env var

Fix priority: PYTHONUTF8=1 (global) → PYTHONIOENCODING=utf-8 (stdout/stderr) → LANG=C.UTF-8 (locale).

Note PYTHONUTF8=1 does not override an explicit PYTHONIOENCODING=ascii (reproduced: still errors) — you must change that var to utf-8 directly.

4. Viewer-side mojibake (logs/terminal) — By scenario

If the container output is fine but Windows terminals/old editors show garbage: switch the terminal to UTF-8 (PowerShell: chcp 65001; VS Code: UTF-8 in the bottom-right picker). This is a display-layer problem; fixing the container will not help.

How to confirm it works

docker run --rm -e TZ=Asia/Shanghai <image> date matches the host hour; python3 -c "import sys; print(sys.stdout.encoding)" prints utf-8; Chinese output renders correctly.

Other environments

EnvironmentBehavior
Debian-family imageShips zoneinfo; -e TZ=Asia/Shanghai just works
Alpine base imageNo /usr/share/zoneinfo; TZ=Asia/Shanghai silently ineffective (reproduced)
No tzdata, temporary fix-e TZ=UTC-8 (POSIX, inverted sign = UTC+8; reproduced)
Python default C localePEP 540 auto UTF-8; Chinese prints fine (reproduced)
PYTHONIOENCODING=asciiUnicodeEncodeError (reproduced verbatim)
Windows console reading UTF-8 outputGBK decoding shows mojibake (display layer, not a container issue)

Symptom

# Timezone
$ docker run --rm -e TZ=Asia/Shanghai alpine date
Mon Aug 31 15:09:18 UTC 2026        # still UTC!
$ docker run --rm alpine ls /usr/share/zoneinfo
ls: /usr/share/zoneinfo: No such file or directory

# Garbled text
$ docker run --rm -e PYTHONIOENCODING=ascii python:3.12-alpine python3 -c "print('中文测试')"
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

Signature: TZ=Asia/Shanghai set but date still UTC; the image lacks zoneinfo; a program printing Chinese raises an ascii encoding error.

Cause

Containers default to UTC and do not inherit the host timezone; alpine-class base images lack /usr/share/zoneinfo, so TZ=Asia/Shanghai is ineffective. Garbled Chinese = the program inside the container is pinned to ASCII/non-UTF-8 output (UnicodeEncodeError), or the viewing terminal's encoding does not match UTF-8 (display mojibake).

Solution

  1. Timezone: -e TZ=Asia/Shanghai on Debian-family images; install tzdata on alpine or use -e TZ=UTC-8 (POSIX, inverted sign) as a stopgap; rebuild the container after changing env;
  2. Encoding: PYTHONUTF8=1 / PYTHONIOENCODING=utf-8 / LANG=C.UTF-8; an explicit ascii pin must be changed to utf-8;
  3. Viewer side: switch the terminal to UTF-8 (chcp 65001, etc.).
Verification Evidence
  • Local reproduction (2026-08-31, custom prebuilt WSL, docker 29.1.3):
  • Host 23:09:18 CST vs container default 15:09:18 UTC (8h off);
  • -e TZ=Asia/Shanghai on alpine → still UTC; ls /usr/share/zoneinfo → No such file;
  • -e TZ=UTC-8 on alpine → 23:09:19 (matches CST; POSIX sign inversion);
  • python default stdout encoding: utf-8, Chinese fine; PYTHONIOENCODING=ascii → UnicodeEncodeError verbatim; PYTHONIOENCODING=utf-8 / PYTHONUTF8=1 → fine;
  • Environment limit: the local alpinelinux mirror is broken (apk add tzdata reports "no such package"), so the standard tzdata path is documented per official docs and was not fully verified locally.

Evidence details kept locally (2026-08-31)

Related canonicals

Read in order: precondition -> same root / same domain / related:

Applicable tools (1)

This problem is linked from the tool pages below — reachable from either side.

docker

Source & evidence

Recorded Verified ✓ VerifiedApplies to 1 tool(s)
Entries contain locally measured or reviewable-source solutions; unmeasured items are explicitly labeled.

← Coding Agents & Terminal domain | Problem Catalog Experience | Facing another issue? Go to the Helpdesk