zoneddatetime-sub-minute-offset.js (6965B)
1 // |reftest| skip-if(!this.hasOwnProperty('Temporal')) -- Temporal is not enabled unconditionally 2 // Copyright (C) 2021 Igalia, S.L. All rights reserved. 3 // This code is governed by the BSD license found in the LICENSE file. 4 5 /*--- 6 esid: sec-temporal.zoneddatetime.from 7 description: Fuzzy matching behaviour with UTC offsets in ISO 8601 strings with named time zones and offset option 8 includes: [temporalHelpers.js] 9 features: [Temporal] 10 ---*/ 11 12 ["use", "ignore", "prefer", "reject"].forEach((offset) => { 13 const result = Temporal.ZonedDateTime.from("1970-01-01T12:00-00:44:30[Africa/Monrovia]", { offset }); 14 assert.sameValue(result.epochNanoseconds, 45870_000_000_000n, `accepts the exact offset string (offset: ${offset})`); 15 assert.sameValue(result.offset, "-00:44:30", "offset property is correct"); 16 }); 17 18 ["use", "ignore", "prefer", "reject"].forEach((offset) => { 19 const result = Temporal.ZonedDateTime.from("1970-01-01T12:00-00:44:30.000000000[Africa/Monrovia]", { offset }); 20 assert.sameValue( 21 result.epochNanoseconds, 22 45870_000_000_000n, 23 `accepts trailing zeroes after ISO string offset (offset: ${offset})` 24 ); 25 assert.sameValue(result.offset, "-00:44:30", "offset property removes trailing zeroes from input"); 26 }); 27 28 assert.throws( 29 RangeError, 30 () => Temporal.ZonedDateTime.from("1970-01-01T00:00-00:44:30[-00:45]", { offset: "reject" }), 31 "minute rounding not supported for offset time zones" 32 ); 33 34 const str = "1970-01-01T12:00-00:45[Africa/Monrovia]"; 35 36 ["ignore", "prefer", "reject"].forEach((offset) => { 37 const result = Temporal.ZonedDateTime.from(str, { offset }); 38 assert.sameValue( 39 result.epochNanoseconds, 40 45870_000_000_000n, 41 `accepts the offset string rounded to minutes (offset=${offset})` 42 ); 43 assert.sameValue(result.offset, "-00:44:30", "offset property is still the full precision"); 44 TemporalHelpers.assertPlainDateTime( 45 result.toPlainDateTime(), 46 1970, 47 1, 48 "M01", 49 1, 50 12, 51 0, 52 0, 53 0, 54 0, 55 0, 56 "wall time is preserved" 57 ); 58 }); 59 60 const result = Temporal.ZonedDateTime.from(str, { offset: "use" }); 61 assert.sameValue( 62 result.epochNanoseconds, 63 45900_000_000_000n, 64 "prioritizes the offset string with HH:MM precision when offset=use" 65 ); 66 assert.sameValue(result.offset, "-00:44:30", "offset property is still the full precision"); 67 TemporalHelpers.assertPlainDateTime( 68 result.toPlainDateTime(), 69 1970, 70 1, 71 "M01", 72 1, 73 12, 74 0, 75 30, 76 0, 77 0, 78 0, 79 "wall time is shifted by the difference between exact and rounded offset" 80 ); 81 82 const wrongSeconds = "1970-01-01T12-00:44:40[Africa/Monrovia]"; 83 const roundedSeconds = "1970-01-01T12-00:45:00[Africa/Monrovia]"; 84 85 const useResultWrongSeconds = Temporal.ZonedDateTime.from(wrongSeconds, { offset: "use" }); 86 assert.sameValue( 87 useResultWrongSeconds.epochNanoseconds, 88 45880_000_000_000n, 89 "uses the wrong offset with HH:MM:SS precision when offset=use" 90 ); 91 assert.sameValue(useResultWrongSeconds.offset, "-00:44:30", "offset property is still the full precision"); 92 TemporalHelpers.assertPlainDateTime( 93 useResultWrongSeconds.toPlainDateTime(), 94 1970, 95 1, 96 "M01", 97 1, 98 12, 99 0, 100 10, 101 0, 102 0, 103 0, 104 "wall time is shifted by the difference between exact and given offset" 105 ); 106 107 108 const useResultRoundedSeconds = Temporal.ZonedDateTime.from(roundedSeconds, { offset: "use" }); 109 assert.sameValue( 110 useResultRoundedSeconds.epochNanoseconds, 111 45900_000_000_000n, 112 "uses the rounded offset with HH:MM:SS precision when offset=use" 113 ); 114 assert.sameValue(useResultRoundedSeconds.offset, "-00:44:30", "offset property is still the full precision"); 115 TemporalHelpers.assertPlainDateTime( 116 useResultRoundedSeconds.toPlainDateTime(), 117 1970, 118 1, 119 "M01", 120 1, 121 12, 122 0, 123 30, 124 0, 125 0, 126 0, 127 "wall time is shifted by the difference between exact and given offset" 128 ); 129 130 ["ignore", "prefer"].forEach((offset) => { 131 const resultWrongSeconds = Temporal.ZonedDateTime.from(wrongSeconds, { offset }); 132 assert.sameValue( 133 resultWrongSeconds.epochNanoseconds, 134 45870_000_000_000n, 135 `does not use the offset string with wrong :SS (offset=${offset})` 136 ); 137 assert.sameValue(resultWrongSeconds.offset, "-00:44:30", "offset property is still the full precision"); 138 TemporalHelpers.assertPlainDateTime( 139 resultWrongSeconds.toPlainDateTime(), 140 1970, 141 1, 142 "M01", 143 1, 144 12, 145 0, 146 0, 147 0, 148 0, 149 0, 150 "wall time is preserved" 151 ); 152 153 const resultRoundedSeconds = Temporal.ZonedDateTime.from(roundedSeconds, { offset }); 154 assert.sameValue( 155 resultRoundedSeconds.epochNanoseconds, 156 45870_000_000_000n, 157 `does not use the offset string with rounded HH:MM:SS (offset=${offset})` 158 ); 159 assert.sameValue(resultRoundedSeconds.offset, "-00:44:30", "offset property is still the full precision"); 160 TemporalHelpers.assertPlainDateTime( 161 resultRoundedSeconds.toPlainDateTime(), 162 1970, 163 1, 164 "M01", 165 1, 166 12, 167 0, 168 0, 169 0, 170 0, 171 0, 172 "wall time is preserved" 173 ); 174 }); 175 176 assert.throws( 177 RangeError, 178 () => Temporal.ZonedDateTime.from(wrongSeconds, { offset: "reject" }), 179 "wrong :SS not accepted in string offset (offset=reject)" 180 ); 181 182 assert.throws( 183 RangeError, 184 () => Temporal.ZonedDateTime.from(roundedSeconds, { offset: "reject" }), 185 "rounded HH:MM:SS not accepted in string offset (offset=reject)" 186 ); 187 188 const properties = { year: 1970, month: 1, day: 1, hour: 12, offset: "-00:45", timeZone: "Africa/Monrovia" }; 189 190 ["ignore", "prefer"].forEach((offset) => { 191 const result = Temporal.ZonedDateTime.from(properties, { offset }); 192 assert.sameValue( 193 result.epochNanoseconds, 194 45870_000_000_000n, 195 `no fuzzy matching is done on offset in property bag (offset=${offset})` 196 ); 197 }); 198 199 const result2 = Temporal.ZonedDateTime.from(properties, { offset: "use" }); 200 assert.sameValue( 201 result2.epochNanoseconds, 202 45900_000_000_000n, 203 "no fuzzy matching is done on offset in property bag (offset=use)" 204 ); 205 206 assert.throws( 207 RangeError, 208 () => Temporal.ZonedDateTime.from(properties, { offset: "reject" }), 209 "no fuzzy matching is done on offset in property bag (offset=reject)" 210 ); 211 212 // Pacific/Niue edge case 213 214 const reference = -543069621_000_000_000n; 215 216 assert.sameValue( 217 Temporal.ZonedDateTime.from("1952-10-15T23:59:59-11:19:40[Pacific/Niue]").epochNanoseconds, 218 reference, 219 "-11:19:40 is accepted as -11:19:40 in Pacific/Niue edge case" 220 ); 221 assert.sameValue( 222 Temporal.ZonedDateTime.from("1952-10-15T23:59:59-11:20[Pacific/Niue]").epochNanoseconds, 223 reference, 224 "-11:20 matches the first candidate -11:19:40 in the Pacific/Niue edge case" 225 ); 226 assert.sameValue( 227 Temporal.ZonedDateTime.from("1952-10-15T23:59:59-11:20:00[Pacific/Niue]").epochNanoseconds, 228 reference + 20_000_000_000n, 229 "-11:20:00 is accepted as -11:20:00 in the Pacific/Niue edge case" 230 ); 231 assert.throws( 232 RangeError, () => Temporal.ZonedDateTime.from("1952-10-15T23:59:59-11:19:50[Pacific/Niue]"), 233 "wrong :SS not accepted in the Pacific/Niue edge case" 234 ); 235 236 reportCompare(0, 0);