diff --git a/src/sources/timezone.test.ts b/src/sources/timezone.test.ts index 61f9157dd..a0bf68ebd 100644 --- a/src/sources/timezone.test.ts +++ b/src/sources/timezone.test.ts @@ -1,3 +1,4 @@ +import { withMockProperties } from '../../tests/utils' import getTimezone from './timezone' describe('Sources', () => { @@ -5,8 +6,8 @@ describe('Sources', () => { it('returns a tz identifier in all supported browsers', () => { const result = getTimezone() - // Some devices on BrowserStack return 'UTC'. - if (result === 'UTC') { + // Some devices on BrowserStack return 'UTC', some '+00:00'. + if (result === 'UTC' || /^[+-]\d{2}:\d{2}$/.test(String(result))) { return } @@ -14,5 +15,51 @@ describe('Sources', () => { // like 'Europe/Berlin' or 'America/Argentina/Buenos_Aires'. expect(result).toMatch(/^([a-z]\/+)?[a-z]+\/[a-z_]+$/gi) }) + + describe('fallbacks', () => { + function withNoTimezone(januaryOffset: number, julyOffset: number, action: () => void) { + class MockDate { + args: unknown[] + + constructor(...args: unknown[]) { + this.args = args + } + + getFullYear() { + return 2024 + } + + getTimezoneOffset() { + if (this.args[1] === 0) { + return januaryOffset + } + if (this.args[1] === 6) { + return julyOffset + } + throw TypeError('Unexpected constructor arguments') + } + } + + return withMockProperties(window, { Date: { value: MockDate }, Intl: undefined }, action) + } + + it('in the northern eastern hemisphere (Berlin)', async () => { + await withNoTimezone(1 * -60, 2 * -60, () => { + expect(getTimezone()).toEqual('UTC+60') + }) + }) + + it('in the southern western hemisphere (Santiago)', async () => { + await withNoTimezone(-3 * -60, -4 * -60, () => { + expect(getTimezone()).toEqual('UTC-240') + }) + }) + + it('in the middle', async () => { + await withNoTimezone(0, 0, () => { + expect(getTimezone()).toEqual('UTC+0') + }) + }) + }) }) }) diff --git a/src/sources/timezone.ts b/src/sources/timezone.ts index 8c55c4324..66af80f1c 100644 --- a/src/sources/timezone.ts +++ b/src/sources/timezone.ts @@ -12,7 +12,7 @@ export default function getTimezone(): string { // For browsers that don't support timezone names // The minus is intentional because the JS offset is opposite to the real offset const offset = -getTimezoneOffset() - return `UTC${offset >= 0 ? '+' : ''}${Math.abs(offset)}` + return `UTC${offset >= 0 ? '+' : ''}${offset}` } function getTimezoneOffset(): number {