From af3d908437b0912513a594e7167f17658e72d88b Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Mon, 15 Sep 2025 17:46:25 -0700 Subject: [PATCH] Temporal: Add tests covering one operand of ZonedDateTime difference at extreme These tests cover the case where the ZonedDateTime since() or until() methods are called with either the receiver or the argument being a ZonedDateTime instance at either the earliest or latest end of the supported range. --- .../prototype/since/argument-at-limits.js | 43 +++++++++++++++++++ .../prototype/until/argument-at-limits.js | 43 +++++++++++++++++++ .../prototype/since/argument-at-limits.js | 43 +++++++++++++++++++ .../prototype/until/argument-at-limits.js | 43 +++++++++++++++++++ 4 files changed, 172 insertions(+) create mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js create mode 100644 test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js create mode 100644 test/intl402/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js b/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js new file mode 100644 index 0000000000..4d4eb5dad1 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js @@ -0,0 +1,43 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: One of the operands is at the limit of the supported epoch ns range +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const max = new Temporal.ZonedDateTime(86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["UTC", "+02:00", "-07:00"]) { + const limit = max.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 1, 1, 1, 1, 1, 1, 1, 1).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.since(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.since(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic since limit with time largestUnit is self-consistent (${timeZone})` + ); +} + +const min = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["UTC", "+00:18", "-08:12"]) { + const limit = min.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 9, 1, 15, 47, 32).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.since(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.since(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic since limit with time largestUnit is self-consistent (${timeZone})` + ); +} diff --git a/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js b/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js new file mode 100644 index 0000000000..7740c8ba06 --- /dev/null +++ b/test/built-ins/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js @@ -0,0 +1,43 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: One of the operands is at the limit of the supported epoch ns range +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const max = new Temporal.ZonedDateTime(86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["UTC", "+02:00", "-07:00"]) { + const limit = max.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 1, 1, 1, 1, 1, 1, 1, 1).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.until(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.until(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic until limit with time largestUnit is self-consistent (${timeZone})` + ); +} + +const min = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["UTC", "+00:18", "-08:12"]) { + const limit = min.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 9, 1, 15, 47, 32).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.until(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.until(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic until limit with time largestUnit is self-consistent (${timeZone})` + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js b/test/intl402/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js new file mode 100644 index 0000000000..962bdeeb41 --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/since/argument-at-limits.js @@ -0,0 +1,43 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.since +description: One of the operands is at the limit of the supported epoch ns range +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const max = new Temporal.ZonedDateTime(86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["Etc/GMT+0", "Europe/Amsterdam", "America/Vancouver"]) { + const limit = max.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 1, 1, 1, 1, 1, 1, 1, 1).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.since(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.since(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic since limit with time largestUnit is self-consistent (${timeZone})` + ); +} + +const min = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["Etc/GMT+0", "Europe/Amsterdam", "America/Vancouver"]) { + const limit = min.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 9, 1, 15, 47, 32).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.since(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.since(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic since limit with time largestUnit is self-consistent (${timeZone})` + ); +} diff --git a/test/intl402/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js b/test/intl402/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js new file mode 100644 index 0000000000..e605096f7e --- /dev/null +++ b/test/intl402/Temporal/ZonedDateTime/prototype/until/argument-at-limits.js @@ -0,0 +1,43 @@ +// Copyright (C) 2025 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.zoneddatetime.prototype.until +description: One of the operands is at the limit of the supported epoch ns range +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const max = new Temporal.ZonedDateTime(86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["Etc/GMT+0", "Europe/Amsterdam", "America/Vancouver"]) { + const limit = max.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 1, 1, 1, 1, 1, 1, 1, 1).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.until(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.until(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic until limit with time largestUnit is self-consistent (${timeZone})` + ); +} + +const min = new Temporal.ZonedDateTime(-86400_0000_0000_000_000_000n, "UTC"); + +for (const timeZone of ["Etc/GMT+0", "Europe/Amsterdam", "America/Vancouver"]) { + const limit = min.withTimeZone(timeZone); + const instance = new Temporal.PlainDateTime(1970, 9, 1, 15, 47, 32).toZonedDateTime(timeZone); + + instance.since(limit, { largestUnit: "years" }); // should not throw + limit.since(instance, { largestUnit: "years" }); // should not throw + + const resultTimeUnit = instance.until(limit, { largestUnit: "seconds" }); + TemporalHelpers.assertDurationsEqual( + limit.until(instance, { largestUnit: "seconds" }), + resultTimeUnit.negated(), + `Arithmetic until limit with time largestUnit is self-consistent (${timeZone})` + ); +}