summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/built-ins/Temporal/Duration/prototype/total/relativeto-zoneddatetime-normalized-time-duration-to-days-range-errors.js
blob: 3150c81852a3efd942000cb3cd06c13918c7c9ec (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
// |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.duration.prototype.total
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]
---*/

const oneNsDuration = Temporal.Duration.from({ nanoseconds: 1 });
const negOneNsDuration = Temporal.Duration.from({ nanoseconds: -1 });
const dayNs = 86_400_000_000_000;
const epochInstant = new Temporal.Instant(0n);

function timeZoneSubstituteValues(
  getPossibleInstantsFor,
  getOffsetNanosecondsFor
) {
  const tz = new Temporal.TimeZone("UTC");
  TemporalHelpers.substituteMethod(
    tz,
    "getPossibleInstantsFor",
    getPossibleInstantsFor
  );
  TemporalHelpers.substituteMethod(
    tz,
    "getOffsetNanosecondsFor",
    getOffsetNanosecondsFor
  );
  return tz;
}

// Step 23: days < 0 and sign = 1
let zdt = new Temporal.ZonedDateTime(
  0n, // Sets _startNs_ to 0
  timeZoneSubstituteValues(
    [[epochInstant]], // Returned in step 16, setting _relativeResult_
    [
      TemporalHelpers.SUBSTITUTE_SKIP, // Pre-conversion in Duration.p.total
      dayNs - 1, // Returned in step 8, setting _startDateTime_
      -dayNs + 1, // Returned in step 9, setting _endDateTime_
    ]
  )
);
assert.throws(RangeError, () =>
  // Using 1ns duration _nanoseconds_ to 1 and _sign_ to 1
  oneNsDuration.total({
    relativeTo: zdt,
    unit: "day",
  }),
  "RangeError when days < 0 and sign = 1"
);

// Step 24: days > 0 and sign = -1
zdt = new Temporal.ZonedDateTime(
  0n, // Sets _startNs_ to 0
  timeZoneSubstituteValues(
    [[epochInstant]], // Returned in step 16, setting _relativeResult_
    [
      TemporalHelpers.SUBSTITUTE_SKIP, // Pre-conversion in Duration.p.total
      -dayNs + 1, // Returned in step 8, setting _startDateTime_
      dayNs - 1, // Returned in step 9, setting _endDateTime_
    ]
  )
);
assert.throws(RangeError, () =>
  // Using -1ns duration sets _nanoseconds_ to -1 and _sign_ to -1
  negOneNsDuration.total({
    relativeTo: zdt,
    unit: "day",
  }),
  "RangeError when days > 0 and sign = -1"
);

// Step 26: nanoseconds > 0 and sign = -1
zdt = new Temporal.ZonedDateTime(
  0n, // Sets _startNs_ to 0
  timeZoneSubstituteValues(
    [
      [new Temporal.Instant(-2n)], // Returned in step 16, setting _relativeResult_
      [new Temporal.Instant(-4n)], // Returned in step 19, setting _oneDayFarther_
    ],
    [
      TemporalHelpers.SUBSTITUTE_SKIP,  // pre-conversion in Duration.p.total
      dayNs - 1, // Returned in step 8, setting _startDateTime_
      -dayNs + 1, // Returned in step 9, setting _endDateTime_
    ]
  )
);
assert.throws(RangeError, () =>
  // Using -1ns duration sets _nanoseconds_ to -1 and _sign_ to -1
  negOneNsDuration.total({
    relativeTo: zdt,
    unit: "day",
  }),
  "RangeError when nanoseconds > 0 and sign = -1"
);

// Step 29: day length is an unsafe integer
zdt = new Temporal.ZonedDateTime(
  0n,
  timeZoneSubstituteValues(
    // 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, () =>
  oneNsDuration.total({
    relativeTo: zdt,
    unit: "days",
  }),
  "Should throw RangeError when time zone calculates an outrageous day length"
);

reportCompare(0, 0);