Yes. The timezone, locale and default character set of the build machine can change dates, sort order and text encoding in what a build produces. Setting TZ to UTC and LC_ALL to C, or C.UTF-8 where UTF-8 is needed, in your build environment removes the variation.
Timezones
The Reproducible Builds documentation shows how a fixed epoch time can still print differently. The same instant formatted as an RFC 2822 date shows a +0100 offset on a machine in that zone and +0000 in UTC. So a tool that writes the timezone makes the output depend on where it ran.
Fixes, in order of preference:
- Use a tool option that forces UTC, such as the utc flag of the date command.
- Otherwise set the TZ environment variable.
The documentation notes TZ=UTC and TZ=UTC0 are both valid, but UTC0 is fully specified by POSIX, while UTC relies on the implementation, usually the IANA database.
Time strings without timezone information are a second problem. A string like a weekday, date and clock time is ambiguous. The docs recommend always including timezone information, or at minimum assuming UTC, since parsing in the build machine's zone can give surprising results, including different hour counts across daylight saving changes. Zip archives store times without a zone, so unpack them with the same timezone each time.
Locales
Locale influences several things:
| Aspect | Variable | Example effect |
|---|---|---|
| Time format | LC_TIME, overridden by LC_ALL | Month and day names differ by language |
| Sort order | LC_COLLATE, overridden by LC_ALL | In a French locale a, B, c sorts case insensitively, while the C locale gives B, a, c |
| Character encoding | LC_CTYPE, overridden by LC_ALL | A text conversion tool gave ISO-8859 output in one locale and UTF-8 in another |
The documentation recommends using LC_ALL directly in build systems, because it overrides the others. The C locale sorts by byte value and is always available. The C.UTF-8 pseudo locale can always be used to get default strings with UTF-8 output.
Where this bites
Sorting is the sneakiest. A script that lists files with sort, or a Makefile that uses wildcard, can order inputs differently depending on locale. The docs show a Makefile using a wildcard that the current locale sorts, and recommend either listing inputs explicitly or using the Make sort function, which does not take locale into account.
Java adds its own variables. For Java 17 and older, the JVM guidance suggests setting file.encoding to UTF-8 and the user language and country properties to fixed values. UTF-8 is the default since Java 18.
Put it in the build, not on the laptop
export TZ=UTC
export LC_ALL=C.UTF-8
Set these in your CI job, your container image or your build wrapper, so everyone gets the same values. Document the choice. Then confirm: build with the variables set, change them to something else such as a French locale and a different zone, rebuild, and compare checksums. If output differs, you found a tool that reads the environment. Use diffoscope to find it. See how to find why two builds differ.
Quick check
Is TZ=UTC enough?
It fixes timezone, but locale and sort order are separate. Set LC_ALL too.
Should developers also set these locally?
If local builds feed releases, yes. Otherwise rely on CI, where the environment is controlled.
Safeguard's dependency scanning and SBOM generation are generally available, and the free scan at gold.safeguard.sh/scan shows what a repository depends on.
Sources
- Reproducible Builds: Timezones
- Reproducible Builds: Locales
- Reproducible Builds: Stable order for inputs
- Reproducible Builds: JVM
Last reviewed: 19 October 2026.