1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally
// 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.zoneddatetime.prototype.until
description: >
Abstract operation NormalizedTimeDurationToDays can throw four different
RangeErrors.
info: |
NormalizedTimeDurationToDays ( norm, zonedRelativeTo, timeZoneRec [ , precalculatedPlainDateTime ] )
22. If days < 0 and sign = 1, throw a RangeError exception.
23. If days > 0 and sign = -1, throw a RangeError exception.
...
25. If NormalizedTimeDurationSign(_norm_) = 1 and sign = -1, throw a RangeError exception.
...
28. If dayLength ≥ 2⁵³, throw a RangeError exception.
features: [Temporal, BigInt]
includes: [temporalHelpers.js]
---*/
function timeZoneSubstituteValues(
getPossibleInstantsFor,
getOffsetNanosecondsFor
) {
const tz = new Temporal.TimeZone("UTC");
TemporalHelpers.substituteMethod(
tz,
"getPossibleInstantsFor",
getPossibleInstantsFor
);
TemporalHelpers.substituteMethod(
tz,
"getOffsetNanosecondsFor",
getOffsetNanosecondsFor
);
return tz;
}
const dayNs = 86_400_000_000_000;
const zeroZDT = new Temporal.ZonedDateTime(0n, "UTC");
const oneZDT = new Temporal.ZonedDateTime(1n, "UTC");
const epochInstant = new Temporal.Instant(0n);
const options = { largestUnit: "days" };
// Step 22: days < 0 and sign = 1
let start = new Temporal.ZonedDateTime(
0n, // Sets DifferenceZonedDateTime _ns1_
timeZoneSubstituteValues(
[[epochInstant]], // Returned in step 16, setting _relativeResult_
[
// Behave normally in 2 calls made prior to NormalizedTimeDurationToDays
TemporalHelpers.SUBSTITUTE_SKIP,
TemporalHelpers.SUBSTITUTE_SKIP,
dayNs - 1, // Returned in step 8, setting _startDateTime_
-dayNs + 1, // Returned in step 9, setting _endDateTime_
]
)
);
assert.throws(RangeError, () =>
start.until(
oneZDT, // Sets DifferenceZonedDateTime _ns2_
options
)
);
// Step 23: days > 0 and sign = -1
start = new Temporal.ZonedDateTime(
1n, // Sets DifferenceZonedDateTime _ns1_
timeZoneSubstituteValues(
[[epochInstant]], // Returned in step 16, setting _relativeResult_
[
// Behave normally in 2 calls made prior to NormalizedTimeDurationToDays
TemporalHelpers.SUBSTITUTE_SKIP,
TemporalHelpers.SUBSTITUTE_SKIP,
-dayNs + 1, // Returned in step 8, setting _startDateTime_
dayNs - 1, // Returned in step 9, setting _endDateTime_
]
)
);
assert.throws(RangeError, () =>
start.until(
zeroZDT, // Sets DifferenceZonedDateTime _ns2_
options
)
);
// Step 25: nanoseconds > 0 and sign = -1
start = new Temporal.ZonedDateTime(
1n, // Sets DifferenceZonedDateTime _ns1_
timeZoneSubstituteValues(
[[new Temporal.Instant(-1n)]], // Returned in step 16, setting _relativeResult_
[
// Behave normally in 2 calls made prior to NormalizedTimeDurationToDays
TemporalHelpers.SUBSTITUTE_SKIP,
TemporalHelpers.SUBSTITUTE_SKIP,
dayNs - 1, // Returned in step 8, setting _startDateTime_
-dayNs + 1, // Returned in step 9, setting _endDateTime_
]
)
);
assert.throws(RangeError, () =>
start.until(
zeroZDT, // Sets DifferenceZonedDateTime _ns2_
options
)
);
// Step 28: day length is an unsafe integer
start = new Temporal.ZonedDateTime(
0n,
timeZoneSubstituteValues(
// Not called in step 16 because _days_ = 0
// Returned in step 21.a, making _oneDayFarther_ 2^53 ns later than _relativeResult_
[[new Temporal.Instant(2n ** 53n)]],
[]
)
);
assert.throws(RangeError, () =>
start.until(
oneZDT,
options
),
"Should throw RangeError when time zone calculates an outrageous day length"
);
reportCompare(0, 0);
|