From ade79462179d70933dfdf35020088b1325fdbda8 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Fri, 6 May 2022 23:40:50 +0200 Subject: [PATCH] LibJS: Simplify DifferenceISODate This is an editorial change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/76452d2 --- .../Runtime/Temporal/CalendarPrototype.cpp | 2 +- .../LibJS/Runtime/Temporal/PlainDate.cpp | 63 +++++-------------- 2 files changed, 18 insertions(+), 47 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp index 7f7f2b0594..150bea2751 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp @@ -208,7 +208,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::date_until) // 7. Let largestUnit be ? ToLargestTemporalUnit(options, ยซ "hour", "minute", "second", "millisecond", "microsecond", "nanosecond" ยป, "auto", "day"). auto largest_unit = TRY(to_largest_temporal_unit(global_object, *options, { "hour"sv, "minute"sv, "second"sv, "millisecond"sv, "microsecond"sv, "nanosecond"sv }, "auto"sv, "day"sv)); - // 8. Let result be ! DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit). + // 8. Let result be DifferenceISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]], largestUnit). auto result = difference_iso_date(global_object, one->iso_year(), one->iso_month(), one->iso_day(), two->iso_year(), two->iso_month(), two->iso_day(), *largest_unit); // 9. Return ! CreateTemporalDuration(result.[[Years]], result.[[Months]], result.[[Weeks]], result.[[Days]], 0, 0, 0, 0, 0, 0). diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp index 1f0b7557e6..9c09a99099 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp @@ -142,10 +142,9 @@ ThrowCompletionOr to_temporal_date(GlobalObject& global_object, Valu // 3.5.3 DifferenceISODate ( y1, m1, d1, y2, m2, d2, largestUnit ), https://tc39.es/proposal-temporal/#sec-temporal-differenceisodate DateDurationRecord difference_iso_date(GlobalObject& global_object, i32 year1, u8 month1, u8 day1, i32 year2, u8 month2, u8 day2, StringView largest_unit) { - // 1. Assert: largestUnit is one of "year", "month", "week", or "day". VERIFY(largest_unit.is_one_of("year"sv, "month"sv, "week"sv, "day"sv)); - // 2. If largestUnit is "year" or "month", then + // 1. If largestUnit is "year" or "month", then if (largest_unit.is_one_of("year"sv, "month"sv)) { // a. Let sign be -(! CompareISODate(y1, m1, d1, y2, m2, d2)). auto sign = -compare_iso_date(year1, month1, day1, year2, month2, day2); @@ -257,65 +256,37 @@ DateDurationRecord difference_iso_date(GlobalObject& global_object, i32 year1, u // t. Return ! CreateDateDurationRecord(years, months, 0, days). return create_date_duration_record(years, months, 0, days); } - // 3. If largestUnit is "day" or "week", then + // 2. If largestUnit is "day" or "week", then else { - ISODate smaller; - ISODate greater; - i8 sign; + // a. Let epochDays1 be MakeDay(๐”ฝ(y1), ๐”ฝ(m1 - 1), ๐”ฝ(d1)). + auto epoch_days_1 = make_day(year1, month1 - 1, day1); - // a. If ! CompareISODate(y1, m1, d1, y2, m2, d2) < 0, then - if (compare_iso_date(year1, month1, day1, year2, month2, day2) < 0) { - // i. Let smaller be the Record { [[Year]]: y1, [[Month]]: m1, [[Day]]: d1 }. - smaller = { .year = year1, .month = month1, .day = day1 }; + // b. Assert: epochDays1 is finite. + VERIFY(isfinite(epoch_days_1)); - // ii. Let greater be the Record { [[Year]]: y2, [[Month]]: m2, [[Day]]: d2 }. - greater = { .year = year2, .month = month2, .day = day2 }; + // c. Let epochDays2 be MakeDay(๐”ฝ(y2), ๐”ฝ(m2 - 1), ๐”ฝ(d2)). + auto epoch_days_2 = make_day(year2, month2 - 1, day2); - // iii. Let sign be 1. - sign = 1; - } - // b. Else, - else { - // i. Let smaller be the Record { [[Year]]: y2, [[Month]]: m2, [[Day]]: d2 }. - smaller = { .year = year2, .month = month2, .day = day2 }; + // d. Assert: epochDays2 is finite. + VERIFY(isfinite(epoch_days_2)); - // ii. Let greater be the Record { [[Year]]: y1, [[Month]]: m1, [[Day]]: d1 }. - greater = { .year = year1, .month = month1, .day = day1 }; - - // iii. Let sign be -1. - sign = -1; - } - - // c. Let days be ! ToISODayOfYear(greater.[[Year]], greater.[[Month]], greater.[[Day]]) - ! ToISODayOfYear(smaller.[[Year]], smaller.[[Month]], smaller.[[Day]]). - double days = to_iso_day_of_year(greater.year, greater.month, greater.day) - to_iso_day_of_year(smaller.year, smaller.month, smaller.day); - - // d. Let year be smaller.[[Year]]. - auto year = smaller.year; - - // e. Repeat, while year < greater.[[Year]], - while (year < greater.year) { - // i. Set days to days + ! ISODaysInYear(year). - days += iso_days_in_year(year); - - // ii. Set year to year + 1. - year++; - } + // e. Let days be โ„(epochDays2) - โ„(epochDays1). + auto days = epoch_days_2 - epoch_days_1; // f. Let weeks be 0. double weeks = 0; // g. If largestUnit is "week", then if (largest_unit == "week"sv) { - // i. Set weeks to floor(days / 7). - weeks = floor(days / 7); + // i. Set weeks to RoundTowardsZero(days / 7). + weeks = trunc(days / 7); - // ii. Set days to days modulo 7. + // ii. Set days to remainder(days, 7). days = fmod(days, 7); } - // h. Return ! CreateDateDurationRecord(0, 0, weeks ร— sign, days ร— sign). - // NOTE: We set weeks and days conditionally to avoid negative zero for 0 * -1. - return create_date_duration_record(0, 0, (weeks != 0) ? weeks * sign : 0, (days != 0) ? days * sign : 0); + // h. Return ! CreateDateDurationRecord(0, 0, weeks, days). + return create_date_duration_record(0, 0, weeks, days); } VERIFY_NOT_REACHED(); }