Skip to content

Commit 37f49d5

Browse files
trflynn89gmta
authored andcommitted
LibJS: Use nanoseconds to normalize values in IsValidDuration
This is an editorial change in the Temporal proposal. See: tc39/proposal-temporal@68004cc tc39/proposal-temporal@a6043aa tc39/proposal-temporal@1962c8b Note that we were already performing this calculation using nanoseconds.
1 parent 8feabc3 commit 37f49d5

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

Libraries/LibJS/Runtime/Temporal/Duration.cpp

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -508,22 +508,23 @@ bool is_valid_duration(double years, double months, double weeks, double days, d
508508
if (AK::fabs(weeks) > NumericLimits<u32>::max())
509509
return false;
510510

511-
// 6. Let normalizedSeconds be days × 86,400 + hours × 3600 + minutes × 60 + seconds + ℝ(𝔽(milliseconds)) × 10**-3 + ℝ(𝔽(microseconds)) × 10**-6 + ℝ(𝔽(nanoseconds)) × 10**-9.
512-
// 7. NOTE: The above step cannot be implemented directly using floating-point arithmetic. Multiplying by 10**-3,
513-
// 10**-6, and 10**-9 respectively may be imprecise when milliseconds, microseconds, or nanoseconds is an
514-
// unsafe integer. This multiplication can be implemented in C++ with an implementation of std::remquo()
515-
// with sufficient bits in the quotient. String manipulation will also give an exact result, since the
511+
// 6. Let normalizedNanoseconds be days × 86,400 × 10**9 + hours × 3600 × 10**9 + minutes × 60 × 10**9 + seconds × 10**9 + ℝ(𝔽(milliseconds)) × 10**6 + ℝ(𝔽(microseconds)) × 10**3 + ℝ(𝔽(nanoseconds)).
512+
// 7. NOTE: The above step cannot be implemented directly using 64-bit floating-point arithmetic. Multiplying by
513+
// 10**-3, 10**-6, and 10**-9 respectively may be imprecise when milliseconds, microseconds, or nanoseconds
514+
// is an unsafe integer. The step can be implemented by using 128-bit integers and performing all arithmetic
515+
// on nanosecond values. It could also be implemented in C++ with an implementation of std::remquo() with
516+
// sufficient bits in the quotient. String manipulation will also give an exact result, since the
516517
// multiplication is by a power of 10.
517-
auto normalized_seconds = TimeDuration { days }.multiplied_by(NANOSECONDS_PER_DAY);
518-
normalized_seconds = normalized_seconds.plus(TimeDuration { hours }.multiplied_by(NANOSECONDS_PER_HOUR));
519-
normalized_seconds = normalized_seconds.plus(TimeDuration { minutes }.multiplied_by(NANOSECONDS_PER_MINUTE));
520-
normalized_seconds = normalized_seconds.plus(TimeDuration { seconds }.multiplied_by(NANOSECONDS_PER_SECOND));
521-
normalized_seconds = normalized_seconds.plus(TimeDuration { milliseconds }.multiplied_by(NANOSECONDS_PER_MILLISECOND));
522-
normalized_seconds = normalized_seconds.plus(TimeDuration { microseconds }.multiplied_by(NANOSECONDS_PER_MICROSECOND));
523-
normalized_seconds = normalized_seconds.plus(TimeDuration { nanoseconds });
524-
525-
// 8. If abs(normalizedSeconds) ≥ 2**53, return false.
526-
if (normalized_seconds.unsigned_value() > MAX_TIME_DURATION.unsigned_value())
518+
auto normalized_nanoseconds = TimeDuration { days }.multiplied_by(NANOSECONDS_PER_DAY);
519+
normalized_nanoseconds = normalized_nanoseconds.plus(TimeDuration { hours }.multiplied_by(NANOSECONDS_PER_HOUR));
520+
normalized_nanoseconds = normalized_nanoseconds.plus(TimeDuration { minutes }.multiplied_by(NANOSECONDS_PER_MINUTE));
521+
normalized_nanoseconds = normalized_nanoseconds.plus(TimeDuration { seconds }.multiplied_by(NANOSECONDS_PER_SECOND));
522+
normalized_nanoseconds = normalized_nanoseconds.plus(TimeDuration { milliseconds }.multiplied_by(NANOSECONDS_PER_MILLISECOND));
523+
normalized_nanoseconds = normalized_nanoseconds.plus(TimeDuration { microseconds }.multiplied_by(NANOSECONDS_PER_MICROSECOND));
524+
normalized_nanoseconds = normalized_nanoseconds.plus(TimeDuration { nanoseconds });
525+
526+
// 8. If abs(normalizedNanoseconds) ≥ 10**9 × 2**53, return false.
527+
if (normalized_nanoseconds.unsigned_value() > MAX_TIME_DURATION.unsigned_value())
527528
return false;
528529

529530
// 9. Return true.

0 commit comments

Comments
 (0)