From fc6cf3cb9dfb3a7dfed1a29236e3ffc7b62c8ead Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sat, 7 May 2022 00:52:58 +0200 Subject: [PATCH] LibJS: Remove ToISODayOfWeek This is an editorial change in the Temporal spec. See: https://github.com/tc39/proposal-temporal/commit/3eab7e4 --- .../LibJS/Runtime/Temporal/Calendar.cpp | 51 +++++++------------ .../LibJS/Runtime/Temporal/Calendar.h | 1 - .../Runtime/Temporal/CalendarPrototype.cpp | 17 ++++++- 3 files changed, 32 insertions(+), 37 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index 57827e78a4..c1a0ba0066 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -617,27 +617,7 @@ u8 iso_days_in_month(i32 year, u8 month) return 28 + JS::in_leap_year(time_from_year(year)); } -// 12.2.30 ToISODayOfWeek ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisodayofweek -u8 to_iso_day_of_week(i32 year, u8 month, u8 day) -{ - // 1. Assert: year is an integer. - // 2. Assert: month is an integer. - // 3. Assert: day is an integer. - - // 4. Let date be the date given by year, month, and day. - // 5. Return date's day of the week according to ISO-8601 as an integer. - // NOTE: Implemented based on https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html - auto normalized_month = month + (month < 3 ? 10 : -2); - auto normalized_year = year - (month < 3 ? 1 : 0); - auto century = normalized_year / 100; - auto truncated_year = normalized_year - (century * 100); - auto day_of_week = modulo(day + static_cast((2.6 * normalized_month) - 0.2) - (2 * century) + truncated_year + (truncated_year / 4) + (century / 4), 7); - - // https://cs.uwaterloo.ca/~alopez-o/math-faq/node73.html computes day_of_week as 0 = Sunday, ..., 6 = Saturday, but for ToISODayOfWeek Monday is 1 and Sunday is 7. - return day_of_week == 0 ? 7 : day_of_week; -} - -// 12.2.31 ToISOWeekOfYear ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisoweekofyear +// 12.2.30 ToISOWeekOfYear ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisoweekofyear u8 to_iso_week_of_year(i32 year, u8 month, u8 day) { // 1. Assert: year is an integer. @@ -646,8 +626,11 @@ u8 to_iso_week_of_year(i32 year, u8 month, u8 day) // 4. Let date be the date given by year, month, and day. // 5. Return date's week number according to ISO-8601 as an integer. - auto day_of_year = day_within_year(make_date(make_day(year, month - 1, day), 0)) + 1; - auto day_of_week = to_iso_day_of_week(year, month, day); + auto t = make_date(make_day(year, month - 1, day), 0); + auto day_of_year = day_within_year(t) + 1; + auto day_of_week = week_day(t); + if (day_of_week == 0) + day_of_week = 7; auto week = (day_of_year - day_of_week + 10) / 7; if (week < 1) { @@ -655,7 +638,7 @@ u8 to_iso_week_of_year(i32 year, u8 month, u8 day) // Thursday (i.e. the first day of the given year is a Friday, or day 5), or the previous // year is a leap year and ends with a Friday (i.e. the first day of the given year is a // Saturday, or day 6), it has 53 weeks, and 52 weeks otherwise. - auto day_of_jump = to_iso_day_of_week(year, 1, 1); + auto day_of_jump = week_day(make_date(make_day(year, 0, 1), 0)); if (day_of_jump == 5 || (in_leap_year(time_from_year(year - 1)) && day_of_jump == 6)) return 53; else @@ -669,7 +652,7 @@ u8 to_iso_week_of_year(i32 year, u8 month, u8 day) return week; } -// 12.2.32 BuildISOMonthCode ( month ), https://tc39.es/proposal-temporal/#sec-buildisomonthcode +// 12.2.31 BuildISOMonthCode ( month ), https://tc39.es/proposal-temporal/#sec-buildisomonthcode String build_iso_month_code(u8 month) { // 1. Let numberPart be ToZeroPaddedDecimalString(month, 2). @@ -677,7 +660,7 @@ String build_iso_month_code(u8 month) return String::formatted("M{:02}", month); } -// 12.2.33 ResolveISOMonth ( fields ), https://tc39.es/proposal-temporal/#sec-temporal-resolveisomonth +// 12.2.32 ResolveISOMonth ( fields ), https://tc39.es/proposal-temporal/#sec-temporal-resolveisomonth ThrowCompletionOr resolve_iso_month(GlobalObject& global_object, Object const& fields) { auto& vm = global_object.vm(); @@ -737,7 +720,7 @@ ThrowCompletionOr resolve_iso_month(GlobalObject& global_object, Object return number_part_integer; } -// 12.2.34 ISODateFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isodatefromfields +// 12.2.33 ISODateFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isodatefromfields ThrowCompletionOr iso_date_from_fields(GlobalObject& global_object, Object const& fields, Object const& options) { auto& vm = global_object.vm(); @@ -771,7 +754,7 @@ ThrowCompletionOr iso_date_from_fields(GlobalObject& global_object, Obj return regulate_iso_date(global_object, year.as_double(), month, day.as_double(), overflow); } -// 12.2.35 ISOYearMonthFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isoyearmonthfromfields +// 12.2.34 ISOYearMonthFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isoyearmonthfromfields ThrowCompletionOr iso_year_month_from_fields(GlobalObject& global_object, Object const& fields, Object const& options) { auto& vm = global_object.vm(); @@ -801,7 +784,7 @@ ThrowCompletionOr iso_year_month_from_fields(GlobalObject& global_ return ISOYearMonth { .year = result.year, .month = result.month, .reference_iso_day = 1 }; } -// 12.2.36 ISOMonthDayFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthdayfromfields +// 12.2.35 ISOMonthDayFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthdayfromfields ThrowCompletionOr iso_month_day_from_fields(GlobalObject& global_object, Object const& fields, Object const& options) { auto& vm = global_object.vm(); @@ -859,7 +842,7 @@ ThrowCompletionOr iso_month_day_from_fields(GlobalObject& global_ob return ISOMonthDay { .month = result->month, .day = result->day, .reference_iso_year = reference_iso_year }; } -// 12.2.37 ISOYear ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isoyear +// 12.2.36 ISOYear ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isoyear i32 iso_year(Object& temporal_object) { // 1. Assert: temporalObject has an [[ISOYear]] internal slot. @@ -877,7 +860,7 @@ i32 iso_year(Object& temporal_object) VERIFY_NOT_REACHED(); } -// 12.2.38 ISOMonth ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isomonth +// 12.2.37 ISOMonth ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isomonth u8 iso_month(Object& temporal_object) { // 1. Assert: temporalObject has an [[ISOMonth]] internal slot. @@ -895,7 +878,7 @@ u8 iso_month(Object& temporal_object) VERIFY_NOT_REACHED(); } -// 12.2.39 ISOMonthCode ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthcode +// 12.2.38 ISOMonthCode ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthcode String iso_month_code(Object& temporal_object) { // 1. Assert: temporalObject has an [[ISOMonth]] internal slot. @@ -913,7 +896,7 @@ String iso_month_code(Object& temporal_object) VERIFY_NOT_REACHED(); } -// 12.2.40 ISODay ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthcode +// 12.2.49 ISODay ( temporalObject ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthcode u8 iso_day(Object& temporal_object) { // 1. Assert: temporalObject has an [[ISODay]] internal slot. @@ -931,7 +914,7 @@ u8 iso_day(Object& temporal_object) VERIFY_NOT_REACHED(); } -// 12.2.41 DefaultMergeFields ( fields, additionalFields ), https://tc39.es/proposal-temporal/#sec-temporal-defaultmergefields +// 12.2.40 DefaultMergeFields ( fields, additionalFields ), https://tc39.es/proposal-temporal/#sec-temporal-defaultmergefields ThrowCompletionOr default_merge_fields(GlobalObject& global_object, Object const& fields, Object const& additional_fields) { auto& vm = global_object.vm(); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h index 3ef0ce9907..96516e350f 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h @@ -63,7 +63,6 @@ String format_calendar_annotation(StringView id, StringView show_calendar); ThrowCompletionOr calendar_equals(GlobalObject&, Object& one, Object& two); ThrowCompletionOr consolidate_calendars(GlobalObject&, Object& one, Object& two); u8 iso_days_in_month(i32 year, u8 month); -u8 to_iso_day_of_week(i32 year, u8 month, u8 day); u8 to_iso_week_of_year(i32 year, u8 month, u8 day); String build_iso_month_code(u8 month); ThrowCompletionOr resolve_iso_month(GlobalObject&, Object const& fields); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp index e963b0ed6e..6ac34a9db0 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp @@ -324,8 +324,21 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::day_of_week) // 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). auto* temporal_date = TRY(to_temporal_date(global_object, vm.argument(0))); - // 5. Return 𝔽(! ToISODayOfWeek(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). - return Value(to_iso_day_of_week(temporal_date->iso_year(), temporal_date->iso_month(), temporal_date->iso_day())); + // 5. Let epochDays be MakeDay(𝔽(temporalDate.[[ISOYear]]), 𝔽(temporalDate.[[ISOMonth]] - 1), 𝔽(temporalDate.[[ISODay]])). + auto epoch_days = make_day(temporal_date->iso_year(), temporal_date->iso_month() - 1, temporal_date->iso_day()); + + // 6. Assert: epochDays is finite. + VERIFY(isfinite(epoch_days)); + + // 7. Let dayOfWeek be WeekDay(MakeDate(epochDays, +0𝔽)). + auto day_of_week = week_day(make_date(epoch_days, 0)); + + // 8. If dayOfWeek = +0𝔽, return 7𝔽. + if (day_of_week == 0) + return Value(7); + + // 9. Return dayOfWeek. + return Value(day_of_week); } // 12.4.14 Temporal.Calendar.prototype.dayOfYear ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.dayofyear