Set Playwright’s browser timezoneId, fix an explicit UTC instant, then assert the date your page displays. Keep the Node runner’s time zone separate: changing the browser setting does not change the runner. Playwright documents that distinction in its locale and time-zone controls.
The downloadable check below gives you 12 repeatable Australian cases: Sydney and Brisbane in two seasons, Broken Hill’s half-hour offset, and Lord Howe’s 30-minute daylight-saving change. It serves its own small page on 127.0.0.1, reads the clock rendered in Chromium and saves the assertions as JSON. No proxy or credentials are needed.
Run the clock check
Use Node.js 24. In a macOS or Linux shell:
mkdir australia-clock-demo
cd australia-clock-demo
curl --fail --silent --show-error --output australia-clock-check.mjs https://ipvolt.com/downloads/australia-clock-check.mjs
npm install --no-audit --no-fund --save-exact playwright@1.63.0
npx playwright install chromium
TZ=UTC node australia-clock-check.mjs > results-utc.jsonThe script and README are available directly. Compare your output with the reference JSON, which includes every assertion and the environment, or the reference CSV, which contains selected row fields.
A successful run exits 0 and reports summary.allPassed: true, with total: 12 and passed: 12. That includes the expected clock relationships and the request/error checks. Exit 1 with result JSON means an assertion failed. A launch or dependency error on standard error is a setup failure; if Chromium cannot start on Linux, check Playwright’s browser system dependencies.
For each row, the script creates a fresh browser context, sets its timezoneId, and calls page.clock.setFixedTime(new Date(test.utc)) before loading the page. The UTC input ends in Z, so it identifies the same instant in either runner environment. setFixedTime fixes the values returned by Date.now() and new Date() while timers continue normally; this fixture checks rendered dates. Playwright’s fixed-time API
Keep the Australian exceptions in your test cases
These eight rows use midnight UTC on 15 January 2026 and 15 July 2026. Offsets below are east of UTC. The JSON expresses them as minutes, with the opposite sign to JavaScript’s getTimezoneOffset().
Browser timezoneId | January local time / UTC offset | July local time / UTC offset |
|---|---|---|
Australia/Sydney | 11:00 / +11:00 | 10:00 / +10:00 |
Australia/Brisbane | 10:00 / +10:00 | 10:00 / +10:00 |
Australia/Broken_Hill | 10:30 / +10:30 | 09:30 / +09:30 |
Australia/Lord_Howe | 11:00 / +11:00 | 10:30 / +10:30 |
Sydney and Brisbane agree in July but differ by an hour in January. Broken Hill and Lord Howe also prevent “NSW” from becoming a single clock expectation. NSW’s time definitions and exceptions describe these offsets and Queensland’s lack of daylight saving. The reference results record what this Chromium run rendered at the declared instants.
The remaining four rows bracket the modelled 4 October 2026 changes. Each pair advances UTC by one second:
| Browser zone | UTC snapshots on 3 October 2026 | Local snapshots on 4 October 2026 | Offset change |
|---|---|---|---|
Australia/Lord_Howe | 15:29:59 → 15:30:00 | 01:59:59 → 02:30:00 | +10:30 → +11:00 |
Australia/Sydney | 15:59:59 → 16:00:00 | 01:59:59 → 03:00:00 | +10:00 → +11:00 |
These are synthetic fixed-time snapshots, executed on 26 September 2026 UTC. The October inputs simulate future instants under the rules checked that day; they do not record a live transition or test a timer running across it. The NSW seasonal dates and IANA Australasian rules support the date and offset expectations. Lord Howe’s change is 30 minutes, and it occurs 30 minutes earlier in UTC than Sydney’s change in this pair.
Change the runner without changing the browser result
Run the same file with Perth as the Node runner’s time zone:
TZ=Australia/Perth node australia-clock-check.mjs > results-perth.jsonCompare the 12 rows[].browser objects with results-utc.json. They should match. The runner objects should differ: the UTC run reports offset 0, while Perth reports 480 minutes east of UTC. Node’s TZ environment variable controls the runner.
Both recorded runs passed all 12 rows, with identical browser readings. Whole JSON files will differ because they also retain execution timestamps and runner metadata. This comparison helps catch a test expectation accidentally calculated in the runner’s local zone.
Check that the assertions reject a mistake
The script includes three deliberately wrong modes. Run each command separately if your shell or CI job stops after a nonzero exit:
TZ=UTC node australia-clock-check.mjs one-nsw-clock > wrong-nsw.json
TZ=UTC node australia-clock-check.mjs one-hour-dst > wrong-dst.json
TZ=UTC node australia-clock-check.mjs omit-browser-timezone > wrong-browser-zone.json| Mode | Deliberate mistake | Recorded failing rows |
|---|---|---|
one-nsw-clock | Expect Sydney’s offset at the same instant for Broken Hill and Lord Howe. | 5 of 12 |
one-hour-dst | Expect Lord Howe’s +10:30 standard offset to increase by a full hour. | 2 of 12 |
omit-browser-timezone | Remove the browser setting while retaining the Australian expectations under the UTC runner. | 12 of 12 |
Each mode should exit 1. The first two deliberately change expected values; the third removes a browser control. They demonstrate detection of those specific mistakes. In wrong-nsw.json, the five failed IDs are Broken Hill in January and July, Lord Howe in July, and both Lord Howe boundary snapshots. In wrong-dst.json, Lord Howe in January and the after-change snapshot reject the invented +11:30 offset.
For an unexpected failure in the normal run, inspect summary.failed and that row’s assertions:
| Failed check | What to inspect next |
|---|---|
fixedInstant | Confirm the explicit UTC input and that fixed time is set before the page reads its clock. |
requestedTimezone | Confirm the page belongs to the context with the requested timezoneId. |
expectedOffset or expectedWallTime | Check the row’s date, zone, offset sign and current rules before changing the expectation. |
renderedEqualsSampled | Inspect page errors and any difference between the rendered clock and the later browser reading. |
If every row passes but summary.allPassed is false, also inspect relationshipsMinutes, requests, blockedRequests and pageErrors. The fixture requires the declared offset relationships, exactly 12 requests to its loopback page, and no blocked page requests or page errors.
Apply the controls to your own page
Choose a date display or schedule whose expected behaviour you can state. Keep the explicit UTC input and browser timezoneId, then replace the fixture’s visible-clock assertion with an assertion against that element in your own test. The download itself accepts no external target URL.
Hold other inputs constant for the first comparison: locale, saved preferences, application configuration and test data. If the application intentionally formats a schedule in a fixed business zone, assert that behaviour. A server-generated timestamp or account-level time-zone preference needs its own setup; browser emulation alone does not establish either value.
Start with the relevant January/July pair, then add a boundary case your application supports. Preserve the failed input and JSON environment record when investigating a discrepancy. Changing the expected output merely to match a browser run would remove the independent check.
If the application also makes a decision from the request’s IP location, use a separate exit-location test. The Australia proxy selection page explains how to choose the location evidence that rule needs.
Method and limits
The recorded runs used Node.js 24.20.0, Playwright 1.63.0 and Chromium 153.0.8010.12 on macOS arm64. After dependency installation, each run made 12 requests to its own loopback page, with zero off-origin page attempts and zero page errors. Expected offsets came from the primary sources above; the script compared the page’s rendered clock with a second browser reading.
This covers one browser engine and OS in 12 declared cases. It does not establish timer progression, repeated times when clocks move backward, every Australian territory, your application’s behaviour or Australian IP geography. The checked IANA source was version 2026d. The results’ nodeTz: 2026a describes Node’s time-zone data; Chromium’s internal database version was not measured. Retain version information and recheck rules when upgrading or choosing new dates.
Australian proxy availability has not been confirmed. Get early access. One email when access opens. Nothing else.
Sources & further reading
Technical references used for this guide. Check the documentation for your installed version and your provider’s supported configuration.