mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 16:37:35 +00:00
LibJS: Replace magic nanosecond numbers with constants
This is an editorial change in the Temporal spec.
See: 3fdbfda
This commit is contained in:
parent
3729a910f6
commit
c6f7214a60
9 changed files with 45 additions and 36 deletions
|
@ -44,6 +44,9 @@ constexpr double ms_per_minute = 60'000;
|
|||
constexpr double ms_per_hour = 3'600'000;
|
||||
// https://tc39.es/ecma262/#eqn-msPerDay
|
||||
constexpr double ms_per_day = 86'400'000;
|
||||
// https://tc39.es/proposal-temporal/#eqn-nsPerDay
|
||||
constexpr double ns_per_day = 86'400'000'000'000;
|
||||
static auto const ns_per_day_bigint = "86400000000000"_sbigint;
|
||||
|
||||
u16 day_within_year(double);
|
||||
u8 date_from_time(double);
|
||||
|
|
|
@ -39,8 +39,8 @@ bool is_valid_epoch_nanoseconds(BigInt const& epoch_nanoseconds)
|
|||
{
|
||||
// 1. Assert: Type(epochNanoseconds) is BigInt.
|
||||
|
||||
// 2. If epochNanoseconds < -86400ℤ × 10^17ℤ or epochNanoseconds > 86400ℤ × 10^17ℤ, then
|
||||
if (epoch_nanoseconds.big_integer() < INSTANT_NANOSECONDS_MIN || epoch_nanoseconds.big_integer() > INSTANT_NANOSECONDS_MAX) {
|
||||
// 2. If ℝ(epochNanoseconds) < nsMinInstant or ℝ(epochNanoseconds) > nsMaxInstant, then
|
||||
if (epoch_nanoseconds.big_integer() < ns_min_instant || epoch_nanoseconds.big_integer() > ns_max_instant) {
|
||||
// a. Return false.
|
||||
return false;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ ThrowCompletionOr<BigInt*> parse_temporal_instant(GlobalObject& global_object, S
|
|||
auto* utc = get_epoch_from_iso_parts(global_object, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond);
|
||||
|
||||
// 6. If ℝ(utc) < -8.64 × 10^21 or ℝ(utc) > 8.64 × 10^21, then
|
||||
if (utc->big_integer() < INSTANT_NANOSECONDS_MIN || utc->big_integer() > INSTANT_NANOSECONDS_MAX) {
|
||||
if (utc->big_integer() < ns_min_instant || utc->big_integer() > ns_max_instant) {
|
||||
// a. Throw a RangeError exception.
|
||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidEpochNanoseconds);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,13 @@ private:
|
|||
BigInt const& m_nanoseconds; // [[Nanoseconds]]
|
||||
};
|
||||
|
||||
// -86400 * 10^17
|
||||
auto const INSTANT_NANOSECONDS_MIN = "-8640000000000000000000"_sbigint;
|
||||
// +86400 * 10^17
|
||||
auto const INSTANT_NANOSECONDS_MAX = "8640000000000000000000"_sbigint;
|
||||
// https://tc39.es/proposal-temporal/#eqn-nsMaxInstant
|
||||
// nsMaxInstant = 10^8 × nsPerDay = 8.64 × 10^21
|
||||
static auto const ns_max_instant = "8640000000000000000000"_sbigint;
|
||||
|
||||
// https://tc39.es/proposal-temporal/#eqn-nsMinInstant
|
||||
// nsMinInstant = -nsMaxInstant = -8.64 × 10^21
|
||||
static auto const ns_min_instant = "-8640000000000000000000"_sbigint;
|
||||
|
||||
bool is_valid_epoch_nanoseconds(BigInt const& epoch_nanoseconds);
|
||||
ThrowCompletionOr<Instant*> create_temporal_instant(GlobalObject&, BigInt const& nanoseconds, FunctionObject const* new_target = nullptr);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <AK/TypeCasts.h>
|
||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Temporal/Calendar.h>
|
||||
|
@ -278,35 +279,35 @@ JS_DEFINE_NATIVE_FUNCTION(InstantPrototype::round)
|
|||
double maximum;
|
||||
// 8. If smallestUnit is "hour", then
|
||||
if (smallest_unit == "hour"sv) {
|
||||
// a. Let maximum be 24.
|
||||
maximum = 24;
|
||||
// a. Let maximum be HoursPerDay.
|
||||
maximum = hours_per_day;
|
||||
}
|
||||
// 9. Else if smallestUnit is "minute", then
|
||||
else if (smallest_unit == "minute"sv) {
|
||||
// a. Let maximum be 1440.
|
||||
maximum = 1440;
|
||||
// a. Let maximum be MinutesPerHour × HoursPerDay.
|
||||
maximum = minutes_per_hour * hours_per_day;
|
||||
}
|
||||
// 10. Else if smallestUnit is "second", then
|
||||
else if (smallest_unit == "second"sv) {
|
||||
// a. Let maximum be 86400.
|
||||
maximum = 86400;
|
||||
// a. Let maximum be SecondsPerMinute × MinutesPerHour × HoursPerDay.
|
||||
maximum = seconds_per_minute * minutes_per_hour * hours_per_day;
|
||||
}
|
||||
// 11. Else if smallestUnit is "millisecond", then
|
||||
else if (smallest_unit == "millisecond"sv) {
|
||||
// a. Let maximum be 8.64 × 10^7.
|
||||
maximum = 86400000;
|
||||
// a. Let maximum be ℝ(msPerDay).
|
||||
maximum = ms_per_day;
|
||||
}
|
||||
// 12. Else if smallestUnit is "microsecond", then
|
||||
else if (smallest_unit == "microsecond"sv) {
|
||||
// a. Let maximum be 8.64 × 10^10.
|
||||
maximum = 86400000000;
|
||||
// a. Let maximum be 10^3 × ℝ(msPerDay).
|
||||
maximum = 1000 * ms_per_day;
|
||||
}
|
||||
// 13. Else,
|
||||
else {
|
||||
// a. Assert: smallestUnit is "nanosecond".
|
||||
VERIFY(smallest_unit == "nanosecond"sv);
|
||||
// b. Let maximum be 8.64 × 10^13.
|
||||
maximum = 86400000000000;
|
||||
// b. Let maximum be nsPerDay.
|
||||
maximum = ns_per_day;
|
||||
}
|
||||
|
||||
// 14. Let roundingIncrement be ? ToTemporalRoundingIncrement(roundTo, maximum, true).
|
||||
|
|
|
@ -164,7 +164,7 @@ BigInt* system_utc_epoch_nanoseconds(GlobalObject& global_object)
|
|||
auto now = Time::now_realtime().to_nanoseconds();
|
||||
auto ns = Crypto::SignedBigInteger::create_from(now);
|
||||
|
||||
// 2. Set ns to the result of clamping ns between -8.64 × 10^21 and 8.64 × 10^21.
|
||||
// 2. Set ns to the result of clamping ns between nsMinInstant and nsMaxInstant.
|
||||
// NOTE: Time::to_nanoseconds() already clamps between -(2^63) and 2^63 - 1, the range of an i64,
|
||||
// if an overflow occurs during seconds -> nanoseconds conversion.
|
||||
|
||||
|
|
|
@ -68,9 +68,9 @@ BigInt* get_epoch_from_iso_parts(GlobalObject& global_object, i32 year, u8 month
|
|||
return js_bigint(vm, Crypto::SignedBigInteger::create_from(static_cast<i64>(ms)).multiplied_by(Crypto::UnsignedBigInteger { 1'000'000 }).plus(Crypto::SignedBigInteger::create_from((i64)microsecond * 1000)).plus(Crypto::SignedBigInteger(nanosecond)));
|
||||
}
|
||||
|
||||
// -864 * 10^19 - 864 * 10^11
|
||||
// nsMinInstant - nsPerDay
|
||||
auto const DATETIME_NANOSECONDS_MIN = "-8640000086400000000000"_sbigint;
|
||||
// +864 * 10^19 + 864 * 10^11
|
||||
// nsMaxInstant + nsPerDay
|
||||
auto const DATETIME_NANOSECONDS_MAX = "8640000086400000000000"_sbigint;
|
||||
|
||||
// 5.5.2 ISODateTimeWithinLimits ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond ), https://tc39.es/proposal-temporal/#sec-temporal-isodatetimewithinlimits
|
||||
|
@ -79,13 +79,13 @@ bool iso_date_time_within_limits(GlobalObject& global_object, i32 year, u8 month
|
|||
// 1. Let ns be ℝ(GetEpochFromISOParts(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)).
|
||||
auto ns = get_epoch_from_iso_parts(global_object, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond)->big_integer();
|
||||
|
||||
// 2. If ns ≤ -8.64 × 10^21 - 8.64 × 10^13, then
|
||||
// 2. If ns ≤ nsMinInstant - nsPerDay, then
|
||||
if (ns <= DATETIME_NANOSECONDS_MIN) {
|
||||
// a. Return false.
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. If ns ≥ 8.64 × 10^21 + 8.64 × 10^13, then
|
||||
// 3. If ns ≥ nsMaxInstant + nsPerDay, then
|
||||
if (ns >= DATETIME_NANOSECONDS_MAX) {
|
||||
// a. Return false.
|
||||
return false;
|
||||
|
@ -328,9 +328,9 @@ ISODateTime round_iso_date_time(i32 year, u8 month, u8 day, u8 hour, u8 minute,
|
|||
{
|
||||
// 1. Assert: year, month, day, hour, minute, second, millisecond, microsecond, and nanosecond are integers.
|
||||
|
||||
// 2. If dayLength is not present, set dayLength to 8.64 × 10^13.
|
||||
// 2. If dayLength is not present, set dayLength to nsPerDay.
|
||||
if (!day_length.has_value())
|
||||
day_length = 86400000000000;
|
||||
day_length = ns_per_day;
|
||||
|
||||
// 3. Let roundedTime be ! RoundTime(hour, minute, second, millisecond, microsecond, nanosecond, increment, unit, roundingMode, dayLength).
|
||||
auto rounded_time = round_time(hour, minute, second, millisecond, microsecond, nanosecond, increment, unit, rounding_mode, day_length);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/Temporal/AbstractOperations.h>
|
||||
|
@ -531,9 +532,9 @@ DaysAndTime round_time(u8 hour, u8 minute, u8 second, u16 millisecond, u16 micro
|
|||
|
||||
// 3. If unit is "day", then
|
||||
if (unit == "day"sv) {
|
||||
// a. If dayLengthNs is not present, set dayLengthNs to 8.64 × 10^13.
|
||||
// a. If dayLengthNs is not present, set dayLengthNs to nsPerDay.
|
||||
if (!day_length_ns.has_value())
|
||||
day_length_ns = 86400000000000;
|
||||
day_length_ns = ns_per_day;
|
||||
|
||||
// b. Let quantity be (((((hour × 60 + minute) × 60 + second) × 1000 + millisecond) × 1000 + microsecond) × 1000 + nanosecond) / dayLengthNs.
|
||||
quantity = (((((hour * 60 + minute) * 60 + second) * 1000 + millisecond) * 1000 + microsecond) * 1000 + nanosecond) / *day_length_ns;
|
||||
|
|
|
@ -491,8 +491,8 @@ ThrowCompletionOr<double> get_offset_nanoseconds_for(GlobalObject& global_object
|
|||
// 5. Set offsetNanoseconds to ℝ(offsetNanoseconds).
|
||||
auto offset_nanoseconds = offset_nanoseconds_value.as_double();
|
||||
|
||||
// 6. If abs(offsetNanoseconds) > 86400 × 10^9, throw a RangeError exception.
|
||||
if (fabs(offset_nanoseconds) > 86400000000000.0)
|
||||
// 6. If abs(offsetNanoseconds) > nsPerDay, throw a RangeError exception.
|
||||
if (fabs(offset_nanoseconds) > ns_per_day)
|
||||
return vm.throw_completion<RangeError>(global_object, ErrorType::TemporalInvalidOffsetNanosecondsValue);
|
||||
|
||||
// 7. Return offsetNanoseconds.
|
||||
|
@ -588,11 +588,11 @@ ThrowCompletionOr<Instant*> disambiguate_possible_instants(GlobalObject& global_
|
|||
// 7. Let epochNanoseconds be GetEpochFromISOParts(dateTime.[[ISOYear]], dateTime.[[ISOMonth]], dateTime.[[ISODay]], dateTime.[[ISOHour]], dateTime.[[ISOMinute]], dateTime.[[ISOSecond]], dateTime.[[ISOMillisecond]], dateTime.[[ISOMicrosecond]], dateTime.[[ISONanosecond]]).
|
||||
auto* epoch_nanoseconds = get_epoch_from_iso_parts(global_object, date_time.iso_year(), date_time.iso_month(), date_time.iso_day(), date_time.iso_hour(), date_time.iso_minute(), date_time.iso_second(), date_time.iso_millisecond(), date_time.iso_microsecond(), date_time.iso_nanosecond());
|
||||
|
||||
// 8. Let dayBefore be ! CreateTemporalInstant(epochNanoseconds - 8.64 × 10^13ℤ).
|
||||
auto* day_before = MUST(create_temporal_instant(global_object, *js_bigint(vm, epoch_nanoseconds->big_integer().minus("86400000000000"_sbigint))));
|
||||
// 8. Let dayBefore be ! CreateTemporalInstant(epochNanoseconds - ℤ(nsPerDay)).
|
||||
auto* day_before = MUST(create_temporal_instant(global_object, *js_bigint(vm, epoch_nanoseconds->big_integer().minus(ns_per_day_bigint))));
|
||||
|
||||
// 9. Let dayAfter be ! CreateTemporalInstant(epochNanoseconds + 8.64 × 10^13ℤ).
|
||||
auto* day_after = MUST(create_temporal_instant(global_object, *js_bigint(vm, epoch_nanoseconds->big_integer().plus("86400000000000"_sbigint))));
|
||||
// 9. Let dayAfter be ! CreateTemporalInstant(epochNanoseconds + ℤ(nsPerDay)).
|
||||
auto* day_after = MUST(create_temporal_instant(global_object, *js_bigint(vm, epoch_nanoseconds->big_integer().plus(ns_per_day_bigint))));
|
||||
|
||||
// 10. Let offsetBefore be ? GetOffsetNanosecondsFor(timeZone, dayBefore).
|
||||
auto offset_before = TRY(get_offset_nanoseconds_for(global_object, time_zone, *day_before));
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibJS/Runtime/GlobalObject.h>
|
||||
#include <LibJS/Runtime/Temporal/Calendar.h>
|
||||
#include <LibJS/Runtime/Temporal/Duration.h>
|
||||
|
@ -439,8 +440,8 @@ ThrowCompletionOr<NanosecondsToDaysResult> nanoseconds_to_days(GlobalObject& glo
|
|||
{
|
||||
auto& vm = global_object.vm();
|
||||
|
||||
// 1. Let dayLengthNs be 8.64 × 10^13.
|
||||
auto day_length_ns = "86400000000000"_sbigint;
|
||||
// 1. Let dayLengthNs be nsPerDay.
|
||||
auto day_length_ns = ns_per_day_bigint;
|
||||
|
||||
// 2. If nanoseconds = 0, then
|
||||
if (nanoseconds == "0"_bigint) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue