Skip to content

Commit 1eee9e6

Browse files
committed
Normative: Look up time zone methods only once
Introduce a new spec type, Time Zone Record, which stores a time zone object's getOffsetNanosecondsFor and getPossibleInstantsFor methods once they have been observably looked up. The record is passed around into abstract operations instead of the time zone object itself Most API operations that do time zone calculations need to look up both getOffsetNanosecondsFor and getPossibleInstantsFor unconditionally. Only in the case where we convert a plain time to an exact time, it's possible we only need to look up getPossibleInstantsFor, or neither (if the offset is supplied.) This is a large commit but most of it is mechanical replacement of Temporal.TimeZone variables with Time Zone Record variables.
1 parent 745c79b commit 1eee9e6

19 files changed

+585
-271
lines changed

polyfill/lib/duration.mjs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
NANOSECONDS,
1616
CALENDAR,
1717
INSTANT,
18-
TIME_ZONE,
1918
CreateSlots,
2019
GetSlot,
2120
SetSlot
@@ -236,7 +235,7 @@ export class Duration {
236235
}
237236

238237
let largestUnit = ES.GetTemporalUnit(roundTo, 'largestUnit', 'datetime', undefined, ['auto']);
239-
let relativeTo = ES.ToRelativeTemporalObject(roundTo);
238+
const { relativeTo, timeZoneRec } = ES.ToRelativeTemporalObject(roundTo);
240239
const roundingIncrement = ES.ToTemporalRoundingIncrement(roundTo);
241240
const roundingMode = ES.ToTemporalRoundingMode(roundTo, 'halfExpand');
242241
let smallestUnit = ES.GetTemporalUnit(roundTo, 'smallestUnit', 'datetime', undefined);
@@ -301,7 +300,12 @@ export class Duration {
301300
if (zonedRelativeTo && plainRelativeToWillBeUsed) {
302301
// Convert a ZonedDateTime relativeTo to PlainDate only if needed in one
303302
// of the operations below, because the conversion is user visible
304-
plainRelativeTo = ES.ToTemporalDate(zonedRelativeTo);
303+
const dt = ES.GetPlainDateTimeFor(
304+
timeZoneRec,
305+
GetSlot(zonedRelativeTo, INSTANT),
306+
GetSlot(zonedRelativeTo, CALENDAR)
307+
);
308+
plainRelativeTo = ES.TemporalDateTimeToDate(dt);
305309
}
306310

307311
({ years, months, weeks, days } = ES.UnbalanceDurationRelative(
@@ -328,7 +332,8 @@ export class Duration {
328332
smallestUnit,
329333
roundingMode,
330334
plainRelativeTo,
331-
zonedRelativeTo
335+
zonedRelativeTo,
336+
timeZoneRec
332337
));
333338
if (zonedRelativeTo) {
334339
({ years, months, weeks, days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } =
@@ -346,7 +351,8 @@ export class Duration {
346351
roundingIncrement,
347352
smallestUnit,
348353
roundingMode,
349-
zonedRelativeTo
354+
zonedRelativeTo,
355+
timeZoneRec
350356
));
351357
}
352358
({ days, hours, minutes, seconds, milliseconds, microseconds, nanoseconds } = ES.BalanceDuration(
@@ -358,7 +364,8 @@ export class Duration {
358364
microseconds,
359365
nanoseconds,
360366
largestUnit,
361-
zonedRelativeTo
367+
zonedRelativeTo,
368+
timeZoneRec
362369
));
363370
({ years, months, weeks, days } = ES.BalanceDurationRelative(
364371
years,
@@ -392,7 +399,7 @@ export class Duration {
392399
} else {
393400
totalOf = ES.GetOptionsObject(totalOf);
394401
}
395-
const relativeTo = ES.ToRelativeTemporalObject(totalOf);
402+
const { relativeTo, timeZoneRec } = ES.ToRelativeTemporalObject(totalOf);
396403
const unit = ES.GetTemporalUnit(totalOf, 'unit', 'datetime', ES.REQUIRED);
397404

398405
let zonedRelativeTo = ES.IsTemporalZonedDateTime(relativeTo) ? relativeTo : undefined;
@@ -402,15 +409,20 @@ export class Duration {
402409
if (zonedRelativeTo !== undefined && plainRelativeToWillBeUsed) {
403410
// Convert a ZonedDateTime relativeTo to PlainDate only if needed in one
404411
// of the operations below, because the conversion is user visible
405-
plainRelativeTo = ES.ToTemporalDate(zonedRelativeTo);
412+
const dt = ES.GetPlainDateTimeFor(
413+
timeZoneRec,
414+
GetSlot(zonedRelativeTo, INSTANT),
415+
GetSlot(zonedRelativeTo, CALENDAR)
416+
);
417+
plainRelativeTo = ES.TemporalDateTimeToDate(dt);
406418
}
407419

408420
// Convert larger units down to days
409421
({ years, months, weeks, days } = ES.UnbalanceDurationRelative(years, months, weeks, days, unit, plainRelativeTo));
410422
// If the unit we're totalling is smaller than `days`, convert days down to that unit.
411423
let intermediate;
412424
if (zonedRelativeTo) {
413-
intermediate = ES.MoveRelativeZonedDateTime(zonedRelativeTo, years, months, weeks, 0);
425+
intermediate = ES.MoveRelativeZonedDateTime(zonedRelativeTo, timeZoneRec, years, months, weeks, 0);
414426
}
415427
let balanceResult = ES.BalancePossiblyInfiniteDuration(
416428
days,
@@ -421,7 +433,8 @@ export class Duration {
421433
microseconds,
422434
nanoseconds,
423435
unit,
424-
intermediate
436+
intermediate,
437+
timeZoneRec
425438
);
426439
if (balanceResult === 'positive overflow') {
427440
return Infinity;
@@ -445,7 +458,8 @@ export class Duration {
445458
unit,
446459
'trunc',
447460
plainRelativeTo,
448-
zonedRelativeTo
461+
zonedRelativeTo,
462+
timeZoneRec
449463
);
450464
return total;
451465
}
@@ -532,19 +546,18 @@ export class Duration {
532546
) {
533547
return 0;
534548
}
535-
const relativeTo = ES.ToRelativeTemporalObject(options);
549+
const { relativeTo, timeZoneRec } = ES.ToRelativeTemporalObject(options);
536550

537551
const calendarUnitsPresent = y1 !== 0 || y2 !== 0 || mon1 !== 0 || mon2 !== 0 || w1 !== 0 || w2 !== 0;
538552

539553
if (ES.IsTemporalZonedDateTime(relativeTo) && (calendarUnitsPresent || d1 != 0 || d2 !== 0)) {
540554
const instant = GetSlot(relativeTo, INSTANT);
541-
const timeZone = GetSlot(relativeTo, TIME_ZONE);
542555
const calendar = GetSlot(relativeTo, CALENDAR);
543-
const precalculatedDateTime = ES.GetPlainDateTimeFor(timeZone, instant, calendar);
556+
const precalculatedDateTime = ES.GetPlainDateTimeFor(timeZoneRec, instant, calendar);
544557

545558
const after1 = ES.AddZonedDateTime(
546559
instant,
547-
timeZone,
560+
timeZoneRec,
548561
calendar,
549562
y1,
550563
mon1,
@@ -560,7 +573,7 @@ export class Duration {
560573
);
561574
const after2 = ES.AddZonedDateTime(
562575
instant,
563-
timeZone,
576+
timeZoneRec,
564577
calendar,
565578
y2,
566579
mon2,

0 commit comments

Comments
 (0)