diff --git a/test/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-combinations-relativeto.js b/test/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-combinations-relativeto.js new file mode 100644 index 0000000000..4f73dd7ac3 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-combinations-relativeto.js @@ -0,0 +1,111 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: Test for all combinations of largestUnit and smallestUnit with relativeTo +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(5, 5, 5, 5, 5, 5, 5, 5, 5, 5); +const plainRelativeTo = new Temporal.PlainDate(2000, 1, 1); +const zonedRelativeTo = new Temporal.ZonedDateTime(63072000_000_000_000n /* = 1972-01-01T00Z */, "UTC"); + +const exactResults = { + years: { + years: [6], + months: [5, 6], + weeks: [5, 6, 1], + days: [5, 6, 0, 10], + hours: [5, 6, 0, 10, 5], + minutes: [5, 6, 0, 10, 5, 5], + seconds: [5, 6, 0, 10, 5, 5, 5], + milliseconds: [5, 6, 0, 10, 5, 5, 5, 5], + microseconds: [5, 6, 0, 10, 5, 5, 5, 5, 5], + nanoseconds: [5, 6, 0, 10, 5, 5, 5, 5, 5, 5], + }, + months: { + months: [0, 66], + weeks: [0, 66, 1], + days: [0, 66, 0, 10], + hours: [0, 66, 0, 10, 5], + minutes: [0, 66, 0, 10, 5, 5], + seconds: [0, 66, 0, 10, 5, 5, 5], + milliseconds: [0, 66, 0, 10, 5, 5, 5, 5], + microseconds: [0, 66, 0, 10, 5, 5, 5, 5, 5], + nanoseconds: [0, 66, 0, 10, 5, 5, 5, 5, 5, 5], + }, + weeks: { + weeks: [0, 0, 288], + days: [0, 0, 288, 2], + hours: [0, 0, 288, 2, 5], + minutes: [0, 0, 288, 2, 5, 5], + seconds: [0, 0, 288, 2, 5, 5, 5], + milliseconds: [0, 0, 288, 2, 5, 5, 5, 5], + microseconds: [0, 0, 288, 2, 5, 5, 5, 5, 5], + nanoseconds: [0, 0, 288, 2, 5, 5, 5, 5, 5, 5], + }, + days: { + days: [0, 0, 0, 2018], + hours: [0, 0, 0, 2018, 5], + minutes: [0, 0, 0, 2018, 5, 5], + seconds: [0, 0, 0, 2018, 5, 5, 5], + milliseconds: [0, 0, 0, 2018, 5, 5, 5, 5], + microseconds: [0, 0, 0, 2018, 5, 5, 5, 5, 5], + nanoseconds: [0, 0, 0, 2018, 5, 5, 5, 5, 5, 5], + }, + hours: { + hours: [0, 0, 0, 0, 48437], + minutes: [0, 0, 0, 0, 48437, 5], + seconds: [0, 0, 0, 0, 48437, 5, 5], + milliseconds: [0, 0, 0, 0, 48437, 5, 5, 5], + microseconds: [0, 0, 0, 0, 48437, 5, 5, 5, 5], + nanoseconds: [0, 0, 0, 0, 48437, 5, 5, 5, 5, 5], + }, + minutes: { + minutes: [0, 0, 0, 0, 0, 2906225], + seconds: [0, 0, 0, 0, 0, 2906225, 5], + milliseconds: [0, 0, 0, 0, 0, 2906225, 5, 5], + microseconds: [0, 0, 0, 0, 0, 2906225, 5, 5, 5], + nanoseconds: [0, 0, 0, 0, 0, 2906225, 5, 5, 5, 5], + }, + seconds: { + seconds: [0, 0, 0, 0, 0, 0, 174373505], + milliseconds: [0, 0, 0, 0, 0, 0, 174373505, 5], + microseconds: [0, 0, 0, 0, 0, 0, 174373505, 5, 5], + nanoseconds: [0, 0, 0, 0, 0, 0, 174373505, 5, 5, 5], + }, + milliseconds: { + milliseconds: [0, 0, 0, 0, 0, 0, 0, 174373505005], + microseconds: [0, 0, 0, 0, 0, 0, 0, 174373505005, 5], + nanoseconds: [0, 0, 0, 0, 0, 0, 0, 174373505005, 5, 5], + }, + microseconds: { + microseconds: [0, 0, 0, 0, 0, 0, 0, 0, 174373505005005], + nanoseconds: [0, 0, 0, 0, 0, 0, 0, 0, 174373505005005, 5], + }, +}; +for (const [largestUnit, entry] of Object.entries(exactResults)) { + for (const [smallestUnit, expected] of Object.entries(entry)) { + for (const relativeTo of [plainRelativeTo, zonedRelativeTo]) { + const [y, mon = 0, w = 0, d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected; + TemporalHelpers.assertDuration( + duration.round({ largestUnit, smallestUnit, relativeTo }), + y, mon, w, d, h, min, s, ms, µs, ns, + `Combination of largestUnit ${largestUnit} and smallestUnit ${smallestUnit}, relative to ${relativeTo}` + ); + } + } +} + +// 174373505005005005 is not a safe integer. +// ℝ(𝔽(174373505005005005)) == 174373505005004992 + +for (const relativeTo of [plainRelativeTo, zonedRelativeTo]) { + TemporalHelpers.assertDuration( + duration.round({ largestUnit: "nanoseconds", smallestUnit: "nanoseconds", relativeTo }), + 0, 0, 0, 0, 0, 0, 0, 0, 0, 174373505005004992, + `Combination of largestUnit nanoseconds and smallestUnit nanoseconds, with precision loss, relative to ${relativeTo}` + ); +} diff --git a/test/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-combinations.js b/test/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-combinations.js new file mode 100644 index 0000000000..7cd9f7fef2 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/round/largestunit-smallestunit-combinations.js @@ -0,0 +1,66 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.round +description: Test for all combinations of largestUnit and smallestUnit without relativeTo +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(0, 0, 0, 5, 5, 5, 5, 5, 5, 5); + +const exactResults = { + days: { + days: [5], + hours: [5, 5], + minutes: [5, 5, 5], + seconds: [5, 5, 5, 5], + milliseconds: [5, 5, 5, 5, 5], + microseconds: [5, 5, 5, 5, 5, 5], + nanoseconds: [5, 5, 5, 5, 5, 5, 5], + }, + hours: { + hours: [0, 125], + minutes: [0, 125, 5], + seconds: [0, 125, 5, 5], + milliseconds: [0, 125, 5, 5, 5], + microseconds: [0, 125, 5, 5, 5, 5], + nanoseconds: [0, 125, 5, 5, 5, 5, 5], + }, + minutes: { + minutes: [0, 0, 7505], + seconds: [0, 0, 7505, 5], + milliseconds: [0, 0, 7505, 5, 5], + microseconds: [0, 0, 7505, 5, 5, 5], + nanoseconds: [0, 0, 7505, 5, 5, 5, 5], + }, + seconds: { + seconds: [0, 0, 0, 450305], + milliseconds: [0, 0, 0, 450305, 5], + microseconds: [0, 0, 0, 450305, 5, 5], + nanoseconds: [0, 0, 0, 450305, 5, 5, 5], + }, + milliseconds: { + milliseconds: [0, 0, 0, 0, 450305005], + microseconds: [0, 0, 0, 0, 450305005, 5], + nanoseconds: [0, 0, 0, 0, 450305005, 5, 5], + }, + microseconds: { + microseconds: [0, 0, 0, 0, 0, 450305005005], + nanoseconds: [0, 0, 0, 0, 0, 450305005005, 5], + }, + nanoseconds: { + nanoseconds: [0, 0, 0, 0, 0, 0, 450305005005005], + }, +}; +for (const [largestUnit, entry] of Object.entries(exactResults)) { + for (const [smallestUnit, expected] of Object.entries(entry)) { + const [d = 0, h = 0, min = 0, s = 0, ms = 0, µs = 0, ns = 0] = expected; + TemporalHelpers.assertDuration( + duration.round({ largestUnit, smallestUnit }), + 0, 0, 0, d, h, min, s, ms, µs, ns, + `Combination of largestUnit ${largestUnit} and smallestUnit ${smallestUnit}` + ); + } +} diff --git a/test/built-ins/Temporal/Duration/prototype/total/dst-day-length.js b/test/built-ins/Temporal/Duration/prototype/total/dst-day-length.js new file mode 100644 index 0000000000..7644c94075 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/total/dst-day-length.js @@ -0,0 +1,146 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.duration.prototype.total +description: > + ZonedDateTime relativeTo affects day length when the duration encompasses a + DST change +includes: [temporalHelpers.js] +features: [Temporal] +---*/ + +const oneDay = new Temporal.Duration(0, 0, 0, 1); +const oneDayNeg = new Temporal.Duration(0, 0, 0, -1); +const hours12 = new Temporal.Duration(0, 0, 0, 0, 12); +const hours12Neg = new Temporal.Duration(0, 0, 0, 0, -12); +const hours25 = new Temporal.Duration(0, 0, 0, 0, 25); +const hours25Neg = new Temporal.Duration(0, 0, 0, 0, -25); +const hours48 = new Temporal.Duration(0, 0, 0, 0, 48); + +const timeZone = TemporalHelpers.springForwardFallBackTimeZone(); + +const skippedHourDay = new Temporal.ZonedDateTime( + 954662400_000_000_000n /* = 2000-04-02T08Z */, + timeZone); /* = 2000-04-02T00-08 in local time */ +const repeatedHourDay = new Temporal.ZonedDateTime( + 972802800_000_000_000n /* = 2000-10-29T07Z */, + timeZone); /* = 2000-10-29T00-07 in local time */ +const inRepeatedHour = new Temporal.ZonedDateTime( + 972806400_000_000_000n /* = 2000-10-29T08Z */, + timeZone); /* = 2000-10-29T01-07 in local time */ +const oneDayAfterRepeatedHour = new Temporal.ZonedDateTime( + 972896400_000_000_000n /* = 2000-10-30T09Z */, + timeZone); /* = 2000-10-30T01-08 in local time */ +const beforeSkippedHour = new Temporal.ZonedDateTime( + 954585000_000_000_000n /* = 2000-04-01T10:30Z */, + timeZone); /* = 2000-04-01T02:30-08 in local time */ +const dayAfterSkippedHour = new Temporal.ZonedDateTime( + 954745200_000_000_000n /* = 2000-04-03T07Z */, + timeZone); /* = 2000-04-03T00-07 in local time */ +const afterSkippedHour = new Temporal.ZonedDateTime( + 954702000_000_000_000n /* = 2000-04-02T19Z */, + timeZone); /* = 2000-04-02T12-07 in local time */ +const afterRepeatedHour = new Temporal.ZonedDateTime( + 972892800_000_000_000n /* = 2000-10-30T08Z */, + timeZone); /* = 2000-10-30T00-08 in local time */ +const afterRepeatedHourSameDay = new Temporal.ZonedDateTime( + 972849600_000_000_000n /* = 2000-10-29T20Z */, + timeZone); /* = 2000-10-29T12-08 in local time */ +const beforeRepeatedHour = new Temporal.ZonedDateTime( + 972716400_000_000_000n /* = 2000-10-28T07Z */, + timeZone); /* = 2000-10-28T00-07 in local time */ + +assert.sameValue(hours25.total({ + unit: "days", + relativeTo: inRepeatedHour +}), 1, "start inside repeated hour, end after: 25 hours = 1 day"); + +assert.sameValue(oneDay.total({ + unit: "hours", + relativeTo: inRepeatedHour +}), 25, "start inside repeated hour, end after: 1 day = 25 hours"); + +assert.sameValue(hours25Neg.total({ + unit: "days", + relativeTo: oneDayAfterRepeatedHour +}), -1, "start after repeated hour, end inside: -25 hours = 1 day"); + +assert.sameValue(oneDayNeg.total({ + unit: "hours", + relativeTo: oneDayAfterRepeatedHour +}), -25, "start after repeated hour, end inside: -1 day = -25 hours"); + +assert.sameValue(hours25.total({ + unit: "days", + relativeTo: beforeSkippedHour +}), 24 / 23, "start in normal hour, end in skipped hour: 25 hours = 1 1/23 day"); + +assert.sameValue(oneDay.total({ + unit: "hours", + relativeTo: beforeSkippedHour +}), 24, "start in normal hour, end in skipped hour: 1 day = 24 hours"); + +assert.sameValue(hours25.total({ + unit: "days", + relativeTo: skippedHourDay +}), 13 / 12, "start before skipped hour, end >1 day after: 25 hours = 1 2/24 day"); + +assert.sameValue(oneDay.total({ + unit: "hours", + relativeTo: skippedHourDay +}), 23, "start before skipped hour, end >1 day after: 1 day = 23 hours"); + +assert.sameValue(hours25Neg.total({ + unit: "days", + relativeTo: dayAfterSkippedHour +}), -13 / 12, "start after skipped hour, end >1 day before: -25 hours = -1 2/24 day"); + +assert.sameValue(oneDayNeg.total({ + unit: "hours", + relativeTo: dayAfterSkippedHour +}), -23, "start after skipped hour, end >1 day before: -1 day = -23 hours"); + +assert.sameValue(hours12.total({ + unit: "days", + relativeTo: skippedHourDay +}), 12 / 23, "start before skipped hour, end <1 day after: 12 hours = 12/23 days"); + +assert.sameValue(hours12Neg.total({ + unit: "days", + relativeTo: afterSkippedHour +}), -12 / 23, "start after skipped hour, end <1 day before: -12 hours = -12/23 days"); + +assert.sameValue(hours25.total({ + unit: "days", + relativeTo: repeatedHourDay +}), 1, "start before repeated hour, end >1 day after: 25 hours = 1 day"); + +assert.sameValue(oneDay.total({ + unit: "hours", + relativeTo: repeatedHourDay +}), 25, "start before repeated hour, end >1 day after: 1 day = 25 hours"); + +assert.sameValue(hours25Neg.total({ + unit: "days", + relativeTo: afterRepeatedHour +}), -1, "start after repeated hour, end >1 day before: -25 hours = -1 day"); + +assert.sameValue(oneDayNeg.total({ + unit: "hours", + relativeTo: afterRepeatedHour +}), -25, "start after repeated hour, end >1 day before: -1 day = -25 hours"); + +assert.sameValue(hours12.total({ + unit: "days", + relativeTo: repeatedHourDay +}), 12 / 25, "start before repeated hour, end <1 day after: 12 hours = 12/25 days"); + +assert.sameValue(hours12Neg.total({ + unit: "days", + relativeTo: afterRepeatedHourSameDay +}), -12 / 25, "start after repeated hour, end <1 day before: -12 hours = -12/25 days"); + +assert.sameValue(hours48.total({ + unit: "days", + relativeTo: beforeRepeatedHour +}), 49 / 25, "start before repeated hour, end after: 48 hours = 1 24/25 days"); diff --git a/test/built-ins/Temporal/Duration/prototype/total/no-dst-day-length.js b/test/built-ins/Temporal/Duration/prototype/total/no-dst-day-length.js new file mode 100644 index 0000000000..19c3eb0652 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/total/no-dst-day-length.js @@ -0,0 +1,27 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-temporal.duration.prototype.total +description: Total day length is 24 hours when not affected by DST +features: [Temporal] +---*/ + +const oneDay = new Temporal.Duration(0, 0, 0, 1); +const hours48 = new Temporal.Duration(0, 0, 0, 0, 48); + +assert.sameValue(oneDay.total("hours"), 24, "with no relativeTo, days are 24 hours"); +assert.sameValue(hours48.total({ unit: "days" }), 2, "with no relativeTo, 48 hours = 2 days"); + +const plainRelativeTo = new Temporal.PlainDate(2017, 1, 1); + +assert.sameValue(oneDay.total({ unit: "hours", relativeTo: plainRelativeTo }), 24, + "with PlainDate relativeTo, days are 24 hours"); +assert.sameValue(hours48.total({ unit: "days", relativeTo: plainRelativeTo }), 2, + "with PlainDate relativeTo, 48 hours = 2 days") + +const zonedRelativeTo = new Temporal.ZonedDateTime(1_000_000_000_000_000_000n, "+04:30"); + +assert.sameValue(oneDay.total({ unit: "hours", relativeTo: zonedRelativeTo }), 24, + "with ZonedDateTime relativeTo, days are 24 hours if the duration encompasses no DST change"); +assert.sameValue(hours48.total({ unit: "days", relativeTo: zonedRelativeTo }), 2, + "with ZonedDateTime relativeTo, 48 hours = 2 days if the duration encompasses no DST change"); diff --git a/test/built-ins/Temporal/Duration/prototype/total/total-of-each-unit-relativeto.js b/test/built-ins/Temporal/Duration/prototype/total/total-of-each-unit-relativeto.js new file mode 100644 index 0000000000..2c73805bf3 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/total/total-of-each-unit-relativeto.js @@ -0,0 +1,43 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: Test representative result for all units, with relativeTo +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(5, 5, 5, 5, 5, 5, 5, 5, 5, 5); +const plainRelativeTo = new Temporal.PlainDate(2000, 1, 1); +const zonedRelativeTo = new Temporal.ZonedDateTime(63072000_000_000_000n /* = 1972-01-01T00Z */, "UTC"); + +const dayMilliseconds = 24 * 3600 * 1000; +const fullYears = 5; +const fullMonths = fullYears * 12 + 5 + 1; +const fullDays = 366 + 365 + 365 + 365 + 366 + 31 + 28 + 31 + 30 + 31 + 5 * 7 + 5; +const fullMilliseconds = fullDays * dayMilliseconds + 5 * 3600_000 + 5 * 60_000 + 5000 + 5; +const partialDayMilliseconds = fullMilliseconds - fullDays * dayMilliseconds + 0.005005; +const fractionalDay = partialDayMilliseconds / dayMilliseconds; +const partialYearDays = fullDays - (fullYears * 365 + 2); +const fractionalYear = partialYearDays / 365 + fractionalDay / 365; +const fractionalMonths = (10 /* = 2025-07-11 - 2025-07-01 */ * dayMilliseconds + partialDayMilliseconds) / (31 * dayMilliseconds); +const totalResults = { + years: fullYears + fractionalYear, + months: fullMonths + fractionalMonths, + weeks: Math.floor(fullDays / 7) + (2 + fractionalDay) / 7, + days: fullDays + fractionalDay, + hours: fullDays * 24 + partialDayMilliseconds / 3600000, + minutes: fullDays * 24 * 60 + partialDayMilliseconds / 60000, + seconds: fullDays * 24 * 60 * 60 + partialDayMilliseconds / 1000, + milliseconds: fullMilliseconds + 0.005005, + microseconds: fullMilliseconds * 1000 + 5.005, + nanoseconds: fullMilliseconds * 1000000 + 5005 +}; +for (const [unit, expected] of Object.entries(totalResults)) { + for (const relativeTo of [plainRelativeTo, zonedRelativeTo]) { + assert.sameValue( + duration.total({ unit, relativeTo }), expected, + `Duration.total results for ${unit} relative to ${relativeTo}` + ); + } +} diff --git a/test/built-ins/Temporal/Duration/prototype/total/total-of-each-unit.js b/test/built-ins/Temporal/Duration/prototype/total/total-of-each-unit.js new file mode 100644 index 0000000000..e08ea0f172 --- /dev/null +++ b/test/built-ins/Temporal/Duration/prototype/total/total-of-each-unit.js @@ -0,0 +1,28 @@ +// Copyright (C) 2024 Igalia, S.L. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-temporal.duration.prototype.total +description: Test representative result for all units, without relativeTo +features: [Temporal] +---*/ + +const duration = new Temporal.Duration(0, 0, 0, 5, 5, 5, 5, 5, 5, 5); + +const dayMilliseconds = 24 * 3600 * 1000; +const fullDays = 5; +const fullMilliseconds = fullDays * dayMilliseconds + 5 * 3600_000 + 5 * 60_000 + 5000 + 5; +const partialDayMilliseconds = fullMilliseconds - fullDays * dayMilliseconds + 0.005005; +const fractionalDay = partialDayMilliseconds / dayMilliseconds; +const totalResults = { + days: fullDays + fractionalDay, + hours: fullDays * 24 + partialDayMilliseconds / 3600000, + minutes: fullDays * 24 * 60 + partialDayMilliseconds / 60000, + seconds: fullDays * 24 * 60 * 60 + partialDayMilliseconds / 1000, + milliseconds: fullMilliseconds + 0.005005, + microseconds: fullMilliseconds * 1000 + 5.005, + nanoseconds: fullMilliseconds * 1000000 + 5005 +}; +for (const [unit, expected] of Object.entries(totalResults)) { + assert.sameValue(duration.total(unit), expected, `Duration.total results for ${unit}`); +} diff --git a/test/staging/Temporal/Duration/old/round.js b/test/staging/Temporal/Duration/old/round.js index 2a4c379f84..edfc1128ff 100644 --- a/test/staging/Temporal/Duration/old/round.js +++ b/test/staging/Temporal/Duration/old/round.js @@ -320,103 +320,6 @@ assert.throws(RangeError, () => d.round({ largestUnit: "nanoseconds" })); var relativeTo = Temporal.PlainDate.from("2020-01-01"); var fortyDays = Temporal.Duration.from({ days: 40 }); assert.sameValue(`${ fortyDays.round({ smallestUnit: "seconds" }) }`, "P40D"); -var roundAndBalanceResults = { - years: { - years: "P6Y", - months: "P5Y6M", - weeks: "P5Y6M1W", - days: "P5Y6M10D", - hours: "P5Y6M10DT5H", - minutes: "P5Y6M10DT5H5M", - seconds: "P5Y6M10DT5H5M5S", - milliseconds: "P5Y6M10DT5H5M5.005S", - microseconds: "P5Y6M10DT5H5M5.005005S", - nanoseconds: "P5Y6M10DT5H5M5.005005005S" - }, - months: { - months: "P66M", - weeks: "P66M1W", - days: "P66M10D", - hours: "P66M10DT5H", - minutes: "P66M10DT5H5M", - seconds: "P66M10DT5H5M5S", - milliseconds: "P66M10DT5H5M5.005S", - microseconds: "P66M10DT5H5M5.005005S", - nanoseconds: "P66M10DT5H5M5.005005005S" - }, - weeks: { - weeks: "P288W", - days: "P288W2D", - hours: "P288W2DT5H", - minutes: "P288W2DT5H5M", - seconds: "P288W2DT5H5M5S", - milliseconds: "P288W2DT5H5M5.005S", - microseconds: "P288W2DT5H5M5.005005S", - nanoseconds: "P288W2DT5H5M5.005005005S" - }, - days: { - days: "P2018D", - hours: "P2018DT5H", - minutes: "P2018DT5H5M", - seconds: "P2018DT5H5M5S", - milliseconds: "P2018DT5H5M5.005S", - microseconds: "P2018DT5H5M5.005005S", - nanoseconds: "P2018DT5H5M5.005005005S" - }, - hours: { - hours: "PT48437H", - minutes: "PT48437H5M", - seconds: "PT48437H5M5S", - milliseconds: "PT48437H5M5.005S", - microseconds: "PT48437H5M5.005005S", - nanoseconds: "PT48437H5M5.005005005S" - }, - minutes: { - minutes: "PT2906225M", - seconds: "PT2906225M5S", - milliseconds: "PT2906225M5.005S", - microseconds: "PT2906225M5.005005S", - nanoseconds: "PT2906225M5.005005005S" - }, - seconds: { - seconds: "PT174373505S", - milliseconds: "PT174373505.005S", - microseconds: "PT174373505.005005S", - nanoseconds: "PT174373505.005005005S" - }, - milliseconds: { - milliseconds: "PT174373505.005S", - microseconds: "PT174373505.005005S", - nanoseconds: "PT174373505.005005005S" - } -}; -for (var [largestUnit, entry] of Object.entries(roundAndBalanceResults)) { - for (var [smallestUnit, expected] of Object.entries(entry)) { - assert.sameValue(`${ d.round({ - largestUnit, - smallestUnit, - relativeTo - }) }`, expected); - } -} -var balanceLosePrecisionResults = { - microseconds: [ - "microseconds", - "nanoseconds" - ], - nanoseconds: ["nanoseconds"] -}; - -// Round may lose precision below ms -for (var [largestUnit, entry] of Object.entries(balanceLosePrecisionResults)) { - for (var smallestUnit of entry) { - assert(`${ d.round({ - largestUnit, - smallestUnit, - relativeTo - }) }`.startsWith("PT174373505.005")); - } -} // halfExpand is the default assert.sameValue(`${ d.round({ diff --git a/test/staging/Temporal/Duration/old/total.js b/test/staging/Temporal/Duration/old/total.js index f12f767aa5..6fb8e009a5 100644 --- a/test/staging/Temporal/Duration/old/total.js +++ b/test/staging/Temporal/Duration/old/total.js @@ -172,47 +172,6 @@ assert(Math.abs(negativeD2.total({ unit: "seconds" }) - -totalD2.seconds) < Numb assert(Math.abs(negativeD2.total({ unit: "milliseconds" }) - -totalD2.milliseconds) < Number.EPSILON); assert(Math.abs(negativeD2.total({ unit: "microseconds" }) - -totalD2.microseconds) < Number.EPSILON); assert.sameValue(negativeD2.total({ unit: "nanoseconds" }), -totalD2.nanoseconds); -var endpoint = relativeTo.toPlainDateTime().add(d); -var options = unit => ({ - largestUnit: unit, - smallestUnit: unit, - roundingMode: "trunc" -}); -var fullYears = 5; -var fullDays = endpoint.since(relativeTo, options("days")).days; -var fullMilliseconds = endpoint.since(relativeTo, options("milliseconds")).milliseconds; -var partialDayMilliseconds = fullMilliseconds - fullDays * 24 * 3600000 + 0.005005; -var fractionalDay = partialDayMilliseconds / (24 * 3600000); -var partialYearDays = fullDays - (fullYears * 365 + 2); -var fractionalYear = partialYearDays / 365 + fractionalDay / 365; -var fractionalMonths = ((endpoint.day - 1) * (24 * 3600000) + partialDayMilliseconds) / (31 * 24 * 3600000); -var totalResults = { - years: fullYears + fractionalYear, - months: 66 + fractionalMonths, - weeks: (fullDays + fractionalDay) / 7, - days: fullDays + fractionalDay, - hours: fullDays * 24 + partialDayMilliseconds / 3600000, - minutes: fullDays * 24 * 60 + partialDayMilliseconds / 60000, - seconds: fullDays * 24 * 60 * 60 + partialDayMilliseconds / 1000, - milliseconds: fullMilliseconds + 0.005005, - microseconds: fullMilliseconds * 1000 + 5.005, - nanoseconds: fullMilliseconds * 1000000 + 5005 -}; -for (var [unit, expected] of Object.entries(totalResults)) { - assert.sameValue(d.total({ - unit, - relativeTo - }).toPrecision(15), expected.toPrecision(15)); -} -for (var unit of [ - "microseconds", - "nanoseconds" - ]) { - assert(d.total({ - unit, - relativeTo - }).toString().startsWith("174373505005")); -} // balances differently depending on relativeTo var fortyDays = Temporal.Duration.from({ days: 40 }); @@ -237,135 +196,9 @@ assert.sameValue(negativeFortyDays.total({ }).toPrecision(16), (-(1 + 9 / 29)).toPrecision(16)); var oneDay = new Temporal.Duration(0, 0, 0, 1); -// relativeTo does not affect days if PlainDate -var relativeTo = Temporal.PlainDate.from("2017-01-01"); -assert.sameValue(oneDay.total({ - unit: "hours", - relativeTo -}), 24); - -// relativeTo does not affect days if ZonedDateTime, and duration encompasses no DST change -var relativeTo = Temporal.ZonedDateTime.from("2017-01-01T00:00[+04:30]"); -assert.sameValue(oneDay.total({ - unit: "hours", - relativeTo -}), 24); - -// relativeTo affects days if ZonedDateTime, and duration encompasses DST change" var timeZone = TemporalHelpers.springForwardFallBackTimeZone(); -var skippedHourDay = Temporal.PlainDateTime.from("2000-04-02").toZonedDateTime(timeZone); -var repeatedHourDay = Temporal.PlainDateTime.from("2000-10-29").toZonedDateTime(timeZone); -var inRepeatedHour = new Temporal.ZonedDateTime(972806400_000_000_000n, timeZone); -var hours12 = new Temporal.Duration(0, 0, 0, 0, 12); var hours25 = new Temporal.Duration(0, 0, 0, 0, 25); -// start inside repeated hour, end after -assert.sameValue(hours25.total({ - unit: "days", - relativeTo: inRepeatedHour -}), 1); -assert.sameValue(oneDay.total({ - unit: "hours", - relativeTo: inRepeatedHour -}), 25); - -// start after repeated hour, end inside (negative) -var relativeTo = Temporal.PlainDateTime.from("2000-10-30T01:00").toZonedDateTime(timeZone); -assert.sameValue(hours25.negated().total({ - unit: "days", - relativeTo -}), -1); -assert.sameValue(oneDay.negated().total({ - unit: "hours", - relativeTo -}), -25); - -// start in normal hour, end in skipped hour -var relativeTo = Temporal.PlainDateTime.from("2000-04-01T02:30").toZonedDateTime(timeZone); -var totalDays = hours25.total({ - unit: "days", - relativeTo -}); -assert(Math.abs(totalDays - (1 + 1 / 23)) < Number.EPSILON); -assert.sameValue(oneDay.total({ - unit: "hours", - relativeTo -}), 24); - -// start before skipped hour, end >1 day after -var totalDays = hours25.total({ - unit: "days", - relativeTo: skippedHourDay -}); -assert(Math.abs(totalDays - (1 + 2 / 24)) < Number.EPSILON); -assert.sameValue(oneDay.total({ - unit: "hours", - relativeTo: skippedHourDay -}), 23); - -// start after skipped hour, end >1 day before (negative) -var relativeTo = Temporal.PlainDateTime.from("2000-04-03T00:00").toZonedDateTime(timeZone); -var totalDays = hours25.negated().total({ - unit: "days", - relativeTo -}); -assert(Math.abs(totalDays - (-1 - 2 / 24)) < Number.EPSILON); -assert.sameValue(oneDay.negated().total({ - unit: "hours", - relativeTo -}), -23); - -// start before skipped hour, end <1 day after -var totalDays = hours12.total({ - unit: "days", - relativeTo: skippedHourDay -}); -assert(Math.abs(totalDays - 12 / 23) < Number.EPSILON); - -// start after skipped hour, end <1 day before (negative) -var relativeTo = Temporal.PlainDateTime.from("2000-04-02T12:00").toZonedDateTime(timeZone); -var totalDays = hours12.negated().total({ - unit: "days", - relativeTo -}); -assert(Math.abs(totalDays - -12 / 23) < Number.EPSILON); - -// start before repeated hour, end >1 day after -assert.sameValue(hours25.total({ - unit: "days", - relativeTo: repeatedHourDay -}), 1); -assert.sameValue(oneDay.total({ - unit: "hours", - relativeTo: repeatedHourDay -}), 25); - -// start after repeated hour, end >1 day before (negative) -var relativeTo = Temporal.PlainDateTime.from("2000-10-30T00:00").toZonedDateTime(timeZone); -assert.sameValue(hours25.negated().total({ - unit: "days", - relativeTo -}), -1); -assert.sameValue(oneDay.negated().total({ - unit: "hours", - relativeTo -}), -25); - -// start before repeated hour, end <1 day after -var totalDays = hours12.total({ - unit: "days", - relativeTo: repeatedHourDay -}); -assert(Math.abs(totalDays - 12 / 25) < Number.EPSILON); - -// start after repeated hour, end <1 day before (negative) -var relativeTo = Temporal.PlainDateTime.from("2000-10-29T12:00").toZonedDateTime(timeZone); -var totalDays = hours12.negated().total({ - unit: "days", - relativeTo -}); -assert(Math.abs(totalDays - -12 / 25) < Number.EPSILON); - // Samoa skipped 24 hours var fakeSamoa = TemporalHelpers.crossDateLineTimeZone(); var relativeTo = Temporal.PlainDateTime.from("2011-12-29T12:00").toZonedDateTime(fakeSamoa); @@ -387,15 +220,6 @@ assert.sameValue(Temporal.Duration.from({ days: 3 }).total({ relativeTo }), 48); -// totaling back up to days -var relativeTo = Temporal.PlainDateTime.from("2000-10-28T00:00").toZonedDateTime(timeZone); -assert.sameValue(Temporal.Duration.from({ hours: 48 }).total({ unit: "days" }), 2); -var totalDays = Temporal.Duration.from({ hours: 48 }).total({ - unit: "days", - relativeTo -}); -assert(Math.abs(totalDays - (1 + 24 / 25)) < Number.EPSILON); - // casts relativeTo to ZonedDateTime if possible assert.sameValue(oneDay.total({ unit: "hours",