Skip to content

Commit 36f288a

Browse files
justingrantptomato
authored andcommitted
Polyfill: Extend transition-finding lookahead
GetNamedTimeZonePreviousTransition currently has an optimization to avoid fruitlessly searching for a transition for far-future dates. This optimization ignores cases where a time zone's offset changes are scheduled more than one year in advance. This commit extends the lookahead period to three years. Similarly, GetNamedTimeZoneNextTransition has an optimization where it assumes that no time zone has any transitions more than one year in the future. This commit extends this lookahead to three years later than either the current date or the input instant, whichever is later. When testing locally, these changes slow down these AOs by 2%-4%, which IMO is an OK tradeoff for more accuracy. Fixes #2564
1 parent 4345a8c commit 36f288a

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

polyfill/lib/ecmascript.mjs

+15-9
Original file line numberDiff line numberDiff line change
@@ -2859,7 +2859,13 @@ export function GetNamedTimeZoneNextTransition(id, epochNanoseconds) {
28592859
if (epochNanoseconds.lesser(BEFORE_FIRST_DST)) {
28602860
return GetNamedTimeZoneNextTransition(id, BEFORE_FIRST_DST);
28612861
}
2862-
const uppercap = SystemUTCEpochNanoSeconds().plus(DAY_NANOS.multiply(366));
2862+
// Optimization: the farthest that we'll look for a next transition is 3 years
2863+
// after the later of epochNanoseconds or the current time. If there are no
2864+
// transitions found before then, we'll assume that there will not be any more
2865+
// transitions after that.
2866+
const now = SystemUTCEpochNanoSeconds();
2867+
const base = epochNanoseconds.greater(now) ? epochNanoseconds : now;
2868+
const uppercap = base.plus(DAY_NANOS.multiply(366 * 3));
28632869
let leftNanos = epochNanoseconds;
28642870
let leftOffsetNs = GetNamedTimeZoneOffsetNanoseconds(id, leftNanos);
28652871
let rightNanos = leftNanos;
@@ -2884,15 +2890,15 @@ export function GetNamedTimeZoneNextTransition(id, epochNanoseconds) {
28842890
}
28852891

28862892
export function GetNamedTimeZonePreviousTransition(id, epochNanoseconds) {
2887-
// Optimization: if the instant is more than a year in the future and there
2888-
// are no transitions between the present day and a year from now, assume
2889-
// there are none after
2893+
// Optimization: if the instant is more than 3 years in the future and there
2894+
// are no transitions between the present day and 3 years from now, assume
2895+
// there are none after.
28902896
const now = SystemUTCEpochNanoSeconds();
2891-
const yearLater = now.plus(DAY_NANOS.multiply(366));
2892-
if (epochNanoseconds.gt(yearLater)) {
2893-
const prevBeforeNextYear = GetNamedTimeZonePreviousTransition(id, yearLater);
2894-
if (prevBeforeNextYear === null || prevBeforeNextYear.lt(now)) {
2895-
return prevBeforeNextYear;
2897+
const lookahead = now.plus(DAY_NANOS.multiply(366 * 3));
2898+
if (epochNanoseconds.gt(lookahead)) {
2899+
const prevBeforeLookahead = GetNamedTimeZonePreviousTransition(id, lookahead);
2900+
if (prevBeforeLookahead === null || prevBeforeLookahead.lt(now)) {
2901+
return prevBeforeLookahead;
28962902
}
28972903
}
28982904

0 commit comments

Comments
 (0)