Skip to content

Commit

Permalink
Temporal: Tests for correct intermediate value in ZonedDateTime diffe…
Browse files Browse the repository at this point in the history
…rence/rounding

These test cases ensure that DST disambiguation does not take place on
intermediate values that are not the start or the end of the calculation.

See tc39/proposal-temporal#2760
  • Loading branch information
ptomato committed Feb 2, 2024
1 parent 3e7938c commit 40d0a71
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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: >
Rounding the resulting duration takes the time zone's UTC offset shifts
into account
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const timeZone = TemporalHelpers.springForwardFallBackTimeZone();

// Based on a test case by Adam Shaw

{
// Date part of duration lands on skipped DST hour, causing disambiguation
const duration = new Temporal.Duration(0, 1, 0, 15, 12);
const relativeTo = new Temporal.ZonedDateTime(
950868000_000_000_000n /* = 2000-02-18T10Z */,
timeZone); /* = 2000-02-18T02-08 in local time */

TemporalHelpers.assertDuration(duration.round({ smallestUnit: "months", relativeTo }),
0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
"1 month 15 days 12 hours should be exactly 1.5 months, which rounds up to 2 months");
TemporalHelpers.assertDuration(duration.round({ smallestUnit: "months", roundingMode: 'halfTrunc', relativeTo }),
0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
"1 month 15 days 12 hours should be exactly 1.5 months, which rounds down to 1 month");
}

{
// Month-only part of duration lands on skipped DST hour, should not cause
// disambiguation
const duration = new Temporal.Duration(0, 1, 0, 15);
const relativeTo = new Temporal.ZonedDateTime(
951991200_000_000_000n /* = 2000-03-02T10Z */,
timeZone); /* = 2000-03-02T02-08 in local time */

TemporalHelpers.assertDuration(duration.round({ smallestUnit: "months", relativeTo }),
0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
"1 month 15 days should be exactly 1.5 months, which rounds up to 2 months");
TemporalHelpers.assertDuration(duration.round({ smallestUnit: "months", roundingMode: 'halfTrunc', relativeTo }),
0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
"1 month 15 days should be exactly 1.5 months, which rounds down to 1 month");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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: >
Rounding the resulting duration takes the time zone's UTC offset shifts
into account
includes: [temporalHelpers.js]
features: [Temporal]
---*/

const timeZone = TemporalHelpers.springForwardFallBackTimeZone();

// Based on a test case by Adam Shaw

{
// Date part of duration lands on skipped DST hour, causing disambiguation
const duration = new Temporal.Duration(0, 1, 0, 15, 12);
const relativeTo = new Temporal.ZonedDateTime(
950868000_000_000_000n /* = 2000-02-18T10Z */,
timeZone); /* = 2000-02-18T02-08 in local time */

assert.sameValue(duration.total({ unit: "months", relativeTo }), 1.5,
"1 month 15 days 12 hours should be exactly 1.5 months");
}

{
// Month-only part of duration lands on skipped DST hour, should not cause
// disambiguation
const duration = new Temporal.Duration(0, 1, 0, 15);
const relativeTo = new Temporal.ZonedDateTime(
951991200_000_000_000n /* = 2000-03-02T10Z */,
timeZone); /* = 2000-03-02T02-08 in local time */

assert.sameValue(duration.total({ unit: "months", relativeTo }), 1.5,
"1 month 15 days should be exactly 1.5 months");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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.zoneddatetime.prototype.since
description: >
Rounding the resulting duration takes the time zone's UTC offset shifts
into account
includes: [temporalHelpers.js]
features: [Temporal]
---*/

// Based on a test case by Adam Shaw

const timeZone = TemporalHelpers.springForwardFallBackTimeZone();

{
// Month-only part of duration lands on skipped DST hour, should not cause
// disambiguation
const start = new Temporal.ZonedDateTime(
950868000_000_000_000n /* = 2000-02-18T10Z */,
timeZone); /* = 2000-02-18T02-08 in local time */
const end = new Temporal.ZonedDateTime(
954709200_000_000_000n /* = 2000-04-02T21Z */,
timeZone); /* = 2000-04-02T14-07 in local time */

const duration = start.since(end, { largestUnit: "months" });
TemporalHelpers.assertDuration(duration, 0, -1, 0, -15, -11, 0, 0, 0, 0, 0,
"1-month rounding window is shortened by DST");
}


{
// Month-only part of duration lands on skipped DST hour, should not cause
// disambiguation
const start = new Temporal.ZonedDateTime(
951991200_000_000_000n /* = 2000-03-02T10Z */,
timeZone); /* = 2000-03-02T02-08 in local time */
const end = new Temporal.ZonedDateTime(
956005200_000_000_000n /* = 2000-04-17T21Z */,
timeZone); /* = 2000-04-17T14-07 in local time */

const duration = start.since(end, { largestUnit: "months" });
TemporalHelpers.assertDuration(duration, 0, -1, 0, -15, -12, 0, 0, 0, 0, 0,
"1-month rounding window is not shortened by DST");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// 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.zoneddatetime.prototype.until
description: >
Rounding the resulting duration takes the time zone's UTC offset shifts
into account
includes: [temporalHelpers.js]
features: [Temporal]
---*/

// Based on a test case by Adam Shaw

const timeZone = TemporalHelpers.springForwardFallBackTimeZone();

{
// Month-only part of duration lands on skipped DST hour, should not cause
// disambiguation
const start = new Temporal.ZonedDateTime(
950868000_000_000_000n /* = 2000-02-18T10Z */,
timeZone); /* = 2000-02-18T02-08 in local time */
const end = new Temporal.ZonedDateTime(
954709200_000_000_000n /* = 2000-04-02T21Z */,
timeZone); /* = 2000-04-02T14-07 in local time */

const duration = start.until(end, { largestUnit: "months" });
TemporalHelpers.assertDuration(duration, 0, 1, 0, 15, 11, 0, 0, 0, 0, 0,
"1-month rounding window is shortened by DST");
}


{
// Month-only part of duration lands on skipped DST hour, should not cause
// disambiguation
const start = new Temporal.ZonedDateTime(
951991200_000_000_000n /* = 2000-03-02T10Z */,
timeZone); /* = 2000-03-02T02-08 in local time */
const end = new Temporal.ZonedDateTime(
956005200_000_000_000n /* = 2000-04-17T21Z */,
timeZone); /* = 2000-04-17T14-07 in local time */

const duration = start.until(end, { largestUnit: "months" });
TemporalHelpers.assertDuration(duration, 0, 1, 0, 15, 12, 0, 0, 0, 0, 0,
"1-month rounding window is not shortened by DST");
}

0 comments on commit 40d0a71

Please sign in to comment.