"useFakeTimers is not supported in this environment" when testing timezone-dependent Intl formatting
0 reputation · 13 Jan 2024, 09:18 UTC
0 reputation · 13 Jan 2024, 09:18 UTC
I need deterministic tests for date formatting that uses Intl.DateTimeFormat with an explicit timeZone option (for example America/New_York). The plan is to freeze the clock with jest.useFakeTimers() and jest.setSystemTime(new Date('2026-10-12T00:00:00Z')) so assertions on formatted output are stable.
Two issues are unclear. First, jest.useFakeTimers() throws "useFakeTimers is not supported in this environment" in environments without timer support, and it is not obvious which Jest test environments (node vs jsdom) and Jest versions (29+ assumed) reliably allow it. Second, even when fake timers work, setSystemTime() appears not to affect how Intl.DateTimeFormat resolves time zones — the formatted output still follows the host's default zone rather than anything controlled by the mock. The documented guidance seems to be setting the TZ environment variable or using a polyfill, but no settled behavior exists across releases.
1. In which Jest environments and versions is the "useFakeTimers is not supported in this environment" error expected, and what triggers it?
2. Is setSystemTime() intended to influence Intl.DateTimeFormat time-zone calculations, or is setting TZ before the test process starts the only supported approach?
3. Is there a documented way to verify that the mocked system time is actually being applied to Intl formatting inside a test?
31275 reputation · 13 Jan 2024, 14:20 UTC
Two separate things are being conflated. The useFakeTimers is not supported in this environment error is about missing timer globals in your test environment, and jest.setSystemTime() was never designed to change time-zone resolution — it only moves the mocked "now". For your stated goal (an explicit timeZone: 'America/New_York' option), fake timers plus setSystemTime are sufficient once the environment problem is fixed; TZ is only needed when code relies on the default zone.
The error is thrown when the active test environment does not expose the timer functions (setTimeout, setInterval, clearTimeout, clearInterval) that @jest/fake-timers needs to replace. The standard node and jsdom environments in Jest 27–29 expose these, so fake timers work there out of the box. The error typically shows up when:
testEnvironment omits the timer globals from its global object.Likely explanation, not confirmed: since you did not post your jest.config, the most common cause is a custom or overridden testEnvironment. Check for a testEnvironment key and, if it points at a custom class, verify it assigns the timer globals. Also confirm your Jest major version: Jest 26 and earlier default to legacy fake timers, where setSystemTime does not exist at all. Jest 27+ defaults to the modern implementation (backed by @sinonjs/fake-timers), which mocks Date and supports setSystemTime.
setSystemTime() only changes what the mocked Date reports as "now". It does not touch the process time zone. Intl.DateTimeFormat resolves the default zone from ICU / the host environment, independently of Jest's clock mock. So:
timeZone option (your case): deterministic with fake timers alone. The instant is frozen by setSystemTime and the zone is fixed by the option, so host TZ is irrelevant.TZ before the Node process starts, e.g. TZ=America/New_York jest in the test script (use cross-env on Windows). Setting process.env.TZ inside a test is unreliable because ICU resolves and caches the zone at process startup.Inside the test, assert the clock first, then inspect what zone the runtime actually uses:
jest.useFakeTimers();
jest.setSystemTime(new Date('2026-10-12T00:00:00Z'));
expect(new Date().toISOString()).toBe('2026-10-12T00:00:00.000Z');
// Which zone does the runtime think it's in?
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
// Deterministic regardless of host zone:
const fmt = new Intl.DateTimeFormat('en-US', {
timeZone: 'America/New_York',
dateStyle: 'short', timeStyle: 'short',
});
expect(fmt.format(new Date())).toBe('10/11/2026, 8:00 PM');A second cross-check: run the suite once with TZ=UTC and once with TZ=America/New_York. If results differ, some code path depends on the default zone and TZ must be pinned in the test script.
small-icu or system ICU may lack full time-zone data, causing formatting differences between machines even with TZ set. Full-icu Node (the default official build) avoids this.Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.