Skip to content

Commit

Permalink
Temporal: Tests for normative changes around date-only strings
Browse files Browse the repository at this point in the history
As per the discussion in
tc39/proposal-temporal#2379 (comment)
and the PR tc39/proposal-temporal#2398, which is
to be presented for consensus to TC39 in the upcoming plenary meeting, UTC
offsets and the Z designator should be disallowed after any date-only
strings (YYYY-MM-DD, YYYY-MM, and MM-DD). They should only be allowed to
follow a time component. Z remains disallowed in any string being parsed
into a Plain type.

Annotations become allowed after any ISO string, even YYYY-MM and MM-DD
where they were previously disallowed.
  • Loading branch information
ptomato committed Nov 30, 2022
1 parent 3775b47 commit e3a393a
Show file tree
Hide file tree
Showing 90 changed files with 3,105 additions and 210 deletions.
5 changes: 3 additions & 2 deletions harness/temporalHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1845,11 +1845,14 @@ var TemporalHelpers = {
plainTimeStringsAmbiguous() {
const ambiguousStrings = [
"2021-12", // ambiguity between YYYY-MM and HHMM-UU
"2021-12[-12:00]", // ditto, TZ does not disambiguate
"1214", // ambiguity between MMDD and HHMM
"0229", // ditto, including MMDD that doesn't occur every year
"1130", // ditto, including DD that doesn't occur in every month
"12-14", // ambiguity between MM-DD and HH-UU
"12-14[-14:00]", // ditto, TZ does not disambiguate
"202112", // ambiguity between YYYYMM and HHMMSS
"202112[UTC]", // ditto, TZ does not disambiguate
];
// Adding a calendar annotation to one of these strings must not cause
// disambiguation in favour of time.
Expand Down Expand Up @@ -1879,8 +1882,6 @@ var TemporalHelpers = {
"0631", // 31 is not a day in June
"0000", // 0 is neither a month nor a day
"00-00", // ditto
"2021-12[-12:00]", // HHMM-UU is ambiguous with YYYY-MM, but TZ disambiguates
"202112[UTC]", // HHMMSS is ambiguous with YYYYMM, but TZ disambiguates
];
},

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.dateadd
description: UTC offset not valid with format that does not include a time
features: [Temporal]
includes: [temporalHelpers.js]
---*/

const instance = new Temporal.Calendar("iso8601");

const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];

for (const arg of validStrings) {
const result = instance.dateAdd(arg, new Temporal.Duration());

TemporalHelpers.assertPlainDate(
result,
2000, 5, "M05", 2,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}

const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];

for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.dateAdd(arg, new Temporal.Duration()),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@ includes: [temporalHelpers.js]
---*/

const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time and no offset"],
["2000-05-02[!Europe/Vienna]", "named, with !, no time, and no offset"],
["2000-05-02[+00:00]", "numeric, with no time and no offset"],
["2000-05-02[!-02:30]", "numeric, with !, no time, and no offset"],
["2000-05-02+00:00[UTC]", "named, with offset and no time"],
["2000-05-02+00:00[!Africa/Abidjan]", "named, with offset, !, and no time"],
["2000-05-02+00:00[-08:00]", "numeric, with offset and no time"],
["2000-05-02+00:00[!+01:00]", "numeric, with offset, !, and no time"],
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.dateuntil
description: UTC offset not valid with format that does not include a time
features: [Temporal]
includes: [temporalHelpers.js]
---*/

const instance = new Temporal.Calendar("iso8601");

const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];

for (const arg of validStrings) {
TemporalHelpers.assertDuration(
instance.dateUntil(arg, arg),
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}

const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];

for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.dateUntil(arg, new Temporal.PlainDate(1977, 11, 19)),
`"${arg}" UTC offset without time is not valid for PlainDate (first argument)`
);
assert.throws(
RangeError,
() => instance.dateUntil(new Temporal.PlainDate(1977, 11, 19), arg),
`"${arg}" UTC offset without time is not valid for PlainDate (second argument)`
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@ includes: [temporalHelpers.js]
---*/

const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time and no offset"],
["2000-05-02[!Europe/Vienna]", "named, with !, no time, and no offset"],
["2000-05-02[+00:00]", "numeric, with no time and no offset"],
["2000-05-02[!-02:30]", "numeric, with !, no time, and no offset"],
["2000-05-02+00:00[UTC]", "named, with offset and no time"],
["2000-05-02+00:00[!Africa/Abidjan]", "named, with offset, !, and no time"],
["2000-05-02+00:00[-08:00]", "numeric, with offset and no time"],
["2000-05-02+00:00[!+01:00]", "numeric, with offset, !, and no time"],
['2000-05-02[Asia/Kolkata]', 'named, with no time'],
['2000-05-02[!Europe/Vienna]', 'named, with ! and no time'],
['2000-05-02[+00:00]', 'numeric, with no time'],
['2000-05-02[!-02:30]', 'numeric, with ! and no time'],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.day
description: UTC offset not valid with format that does not include a time
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];

for (const arg of validStrings) {
const result = instance.day(arg);

assert.sameValue(
result,
2,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}

const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];

for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.day(arg),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@ features: [Temporal]
---*/

const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time and no offset"],
["2000-05-02[!Europe/Vienna]", "named, with !, no time, and no offset"],
["2000-05-02[+00:00]", "numeric, with no time and no offset"],
["2000-05-02[!-02:30]", "numeric, with !, no time, and no offset"],
["2000-05-02+00:00[UTC]", "named, with offset and no time"],
["2000-05-02+00:00[!Africa/Abidjan]", "named, with offset, !, and no time"],
["2000-05-02+00:00[-08:00]", "numeric, with offset and no time"],
["2000-05-02+00:00[!+01:00]", "numeric, with offset, !, and no time"],
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.dayofweek
description: UTC offset not valid with format that does not include a time
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];

for (const arg of validStrings) {
const result = instance.dayOfWeek(arg);

assert.sameValue(
result,
2,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}

const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];

for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.dayOfWeek(arg),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@ features: [Temporal]
---*/

const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time and no offset"],
["2000-05-02[!Europe/Vienna]", "named, with !, no time, and no offset"],
["2000-05-02[+00:00]", "numeric, with no time and no offset"],
["2000-05-02[!-02:30]", "numeric, with !, no time, and no offset"],
["2000-05-02+00:00[UTC]", "named, with offset and no time"],
["2000-05-02+00:00[!Africa/Abidjan]", "named, with offset, !, and no time"],
["2000-05-02+00:00[-08:00]", "numeric, with offset and no time"],
["2000-05-02+00:00[!+01:00]", "numeric, with offset, !, and no time"],
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.dayofyear
description: UTC offset not valid with format that does not include a time
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];

for (const arg of validStrings) {
const result = instance.dayOfYear(arg);

assert.sameValue(
result,
123,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}

const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];

for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.dayOfYear(arg),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,10 @@ features: [Temporal]
---*/

const tests = [
["2000-05-02[Asia/Kolkata]", "named, with no time and no offset"],
["2000-05-02[!Europe/Vienna]", "named, with !, no time, and no offset"],
["2000-05-02[+00:00]", "numeric, with no time and no offset"],
["2000-05-02[!-02:30]", "numeric, with !, no time, and no offset"],
["2000-05-02+00:00[UTC]", "named, with offset and no time"],
["2000-05-02+00:00[!Africa/Abidjan]", "named, with offset, !, and no time"],
["2000-05-02+00:00[-08:00]", "numeric, with offset and no time"],
["2000-05-02+00:00[!+01:00]", "numeric, with offset, !, and no time"],
["2000-05-02[Asia/Kolkata]", "named, with no time"],
["2000-05-02[!Europe/Vienna]", "named, with ! and no time"],
["2000-05-02[+00:00]", "numeric, with no time"],
["2000-05-02[!-02:30]", "numeric, with ! and no time"],
["2000-05-02T15:23[America/Sao_Paulo]", "named, with no offset"],
["2000-05-02T15:23[!Asia/Tokyo]", "named, with ! and no offset"],
["2000-05-02T15:23[-02:30]", "numeric, with no offset"],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2022 Igalia, S.L. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-temporal.calendar.prototype.daysinmonth
description: UTC offset not valid with format that does not include a time
features: [Temporal]
---*/

const instance = new Temporal.Calendar("iso8601");

const validStrings = [
"2000-05-02T00+00:00",
"2000-05-02T00+00:00[UTC]",
"2000-05-02T00+00:00[!UTC]",
"2000-05-02T00-02:30[America/St_Johns]",
];

for (const arg of validStrings) {
const result = instance.daysInMonth(arg);

assert.sameValue(
result,
31,
`"${arg}" is a valid UTC offset with time for PlainDate`
);
}

const invalidStrings = [
"2022-09-15Z",
"2022-09-15Z[UTC]",
"2022-09-15Z[Europe/Vienna]",
"2022-09-15+00:00",
"2022-09-15+00:00[UTC]",
"2022-09-15-02:30",
"2022-09-15-02:30[America/St_Johns]",
];

for (const arg of invalidStrings) {
assert.throws(
RangeError,
() => instance.daysInMonth(arg),
`"${arg}" UTC offset without time is not valid for PlainDate`
);
}
Loading

0 comments on commit e3a393a

Please sign in to comment.