summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/built-ins/Temporal/ZonedDateTime/prototype/until/normalized-time-duration-to-days-range-errors.js
blob: 479dcf0b0c1a48f035a0c62973c2b8c11648b5e9 (plain)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// |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 ] )
    23. If days < 0 and sign = 1, throw a RangeError exception.
    24. If days > 0 and sign = -1, throw a RangeError exception.
    ...
    26. If NormalizedTimeDurationSign(_norm_) = 1 and sign = -1, throw a RangeError exception.
    ...
    29. 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", smallestUnit: "seconds", roundingMode: "expand" };

// Step 23: days < 0 and sign = 1
let start = new Temporal.ZonedDateTime(
  0n, // Sets DifferenceZonedDateTime _ns1_
  timeZoneSubstituteValues(
    [
      TemporalHelpers.SUBSTITUTE_SKIP,  // Behave normally in DifferenceZonedDateTime
      [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
  ),
  "days < 0 and sign = 1"
);

// Step 24: days > 0 and sign = -1
start = new Temporal.ZonedDateTime(
  1n, // Sets DifferenceZonedDateTime _ns1_
  timeZoneSubstituteValues(
    [
      TemporalHelpers.SUBSTITUTE_SKIP,  // Behave normally in DifferenceZonedDateTime
      [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
  ),
  "days > 0 and sign = -1"
);

// Step 26: nanoseconds > 0 and sign = -1
start = new Temporal.ZonedDateTime(
  1n, // Sets DifferenceZonedDateTime _ns1_
  timeZoneSubstituteValues(
    [
      TemporalHelpers.SUBSTITUTE_SKIP,  // Behave normally in DifferenceZonedDateTime
      [new Temporal.Instant(-2_000_000_000n)], // 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
  ),
  "norm > 0 and sign = -1"
);

// Step 29: day length is an unsafe integer
start = new Temporal.ZonedDateTime(
  0n,
  timeZoneSubstituteValues(
    [
      TemporalHelpers.SUBSTITUTE_SKIP,  // Behave normally in DifferenceZonedDateTime
      // Not called in step 16 because _days_ = 0
      // Returned in step 19, 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);