Skip to content

Commit

Permalink
Polyfill: Implement previous commit in reference code
Browse files Browse the repository at this point in the history
Brings the reference code in line with the editorial changes in the spec
text from the previous commit.
  • Loading branch information
ptomato committed Nov 1, 2024
1 parent 367b54e commit c957836
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 27 deletions.
25 changes: 19 additions & 6 deletions polyfill/lib/duration.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
SetSlot,
TIME_ZONE
} from './slots.mjs';
import { TimeDuration } from './timeduration.mjs';

export class Duration {
constructor(
Expand Down Expand Up @@ -282,9 +283,20 @@ export class Duration {
throw new RangeErrorCtor(`a starting point is required for ${largestUnit}s balancing`);
}
assert(!ES.IsCalendarUnit(smallestUnit), 'smallestUnit was larger than largestUnit');
let duration = ES.ToInternalDurationRecordWith24HourDays(this);
duration = ES.RoundTimeDuration(duration, roundingIncrement, smallestUnit, roundingMode);
return ES.TemporalDurationFromInternal(duration, largestUnit);
let internalDuration = ES.ToInternalDurationRecordWith24HourDays(this);
if (smallestUnit === 'day') {
// First convert time units up to days
const DAY_NANOS = 86400 * 1e9;
const { quotient, remainder } = internalDuration.time.divmod(DAY_NANOS);
let days = internalDuration.date.days + quotient + remainder.fdiv(DAY_NANOS);
days = ES.RoundNumberToIncrement(days, roundingIncrement, roundingMode);
const dateDuration = { years: 0, months: 0, weeks: 0, days };
internalDuration = ES.CombineDateAndTimeDuration(dateDuration, TimeDuration.ZERO);
} else {
const timeDuration = ES.RoundTimeDuration(internalDuration.time, roundingIncrement, smallestUnit, roundingMode);
internalDuration = ES.CombineDateAndTimeDuration(ES.ZeroDateDuration(), timeDuration);
}
return ES.TemporalDurationFromInternal(internalDuration, largestUnit);
}
total(totalOf) {
if (!ES.IsTemporalDuration(this)) throw new TypeErrorCtor('invalid receiver');
Expand Down Expand Up @@ -349,10 +361,11 @@ export class Duration {
if (unit === 'nanosecond' && increment === 1) return ES.TemporalDurationToString(this, precision);

const largestUnit = ES.DefaultTemporalLargestUnit(this);
let duration = ES.ToInternalDurationRecord(this);
duration = ES.RoundTimeDuration(duration, increment, unit, roundingMode);
let internalDuration = ES.ToInternalDurationRecord(this);
const timeDuration = ES.RoundTimeDuration(internalDuration.time, increment, unit, roundingMode);
internalDuration = ES.CombineDateAndTimeDuration(internalDuration.date, timeDuration);
const roundedDuration = ES.TemporalDurationFromInternal(
duration,
internalDuration,
ES.LargerOfTwoTemporalUnits(largestUnit, 'second')
);
return ES.TemporalDurationToString(roundedDuration, precision);
Expand Down
36 changes: 15 additions & 21 deletions polyfill/lib/ecmascript.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ export function AdjustDateDurationRecord({ years, months, weeks, days }, newDays
};
}

function ZeroDateDuration() {
export function ZeroDateDuration() {
return { years: 0, months: 0, weeks: 0, days: 0 };
}

Expand Down Expand Up @@ -2952,7 +2952,7 @@ export function TemporalDurationFromInternal(internalDuration, largestUnit) {
);
}

function CombineDateAndTimeDuration(dateDuration, timeDuration) {
export function CombineDateAndTimeDuration(dateDuration, timeDuration) {
const dateSign = DateDurationSign(dateDuration);
const timeSign = timeDuration.sign();
if (dateSign !== 0 && timeSign !== 0 && dateSign !== timeSign) {
Expand Down Expand Up @@ -2994,8 +2994,9 @@ function DifferenceTime(time1, time2) {
}

function DifferenceInstant(ns1, ns2, increment, smallestUnit, roundingMode) {
const diff = { date: ZeroDateDuration(), time: TimeDuration.fromEpochNsDiff(ns2, ns1) };
return RoundTimeDuration(diff, increment, smallestUnit, roundingMode);
let timeDuration = TimeDuration.fromEpochNsDiff(ns2, ns1);
timeDuration = RoundTimeDuration(timeDuration, increment, smallestUnit, roundingMode);
return CombineDateAndTimeDuration(ZeroDateDuration(), timeDuration);
}

function DifferenceISODateTime(isoDateTime1, isoDateTime2, calendar, largestUnit) {
Expand Down Expand Up @@ -3691,10 +3692,13 @@ export function DifferenceTemporalPlainTime(operation, plainTime, other, options
const settings = GetDifferenceSettings(operation, resolvedOptions, 'time', [], 'nanosecond', 'hour');

let timeDuration = DifferenceTime(GetSlot(plainTime, TIME), GetSlot(other, TIME));
let duration = { date: ZeroDateDuration(), time: timeDuration };
if (settings.smallestUnit !== 'nanosecond' || settings.roundingIncrement !== 1) {
duration = RoundTimeDuration(duration, settings.roundingIncrement, settings.smallestUnit, settings.roundingMode);
}
timeDuration = RoundTimeDuration(
timeDuration,
settings.roundingIncrement,
settings.smallestUnit,
settings.roundingMode
);
const duration = CombineDateAndTimeDuration(ZeroDateDuration(), timeDuration);

let result = TemporalDurationFromInternal(duration, settings.largestUnit);
if (operation === 'since') result = CreateNegatedTemporalDuration(result);
Expand Down Expand Up @@ -4060,20 +4064,10 @@ export function RoundTime(
}
}

export function RoundTimeDuration(duration, increment, unit, roundingMode) {
// unit must not be a calendar unit
if (unit === 'day') {
// First convert time units up to days
const { quotient, remainder } = duration.time.divmod(DAY_NANOS);
let days = duration.date.days + quotient + remainder.fdiv(DAY_NANOS);
days = RoundNumberToIncrement(days, increment, roundingMode);
const dateDuration = AdjustDateDurationRecord(duration.date, days);
return CombineDateAndTimeDuration(dateDuration, TimeDuration.ZERO);
}

export function RoundTimeDuration(timeDuration, increment, unit, roundingMode) {
// unit must be a time unit
const divisor = Call(MapPrototypeGet, NS_PER_TIME_UNIT, [unit]);
const timeDuration = duration.time.round(divisor * increment, roundingMode);
return CombineDateAndTimeDuration(duration.date, timeDuration);
return timeDuration.round(divisor * increment, roundingMode);
}

export function TotalTimeDuration(timeDuration, unit) {
Expand Down

0 comments on commit c957836

Please sign in to comment.