From fa1416987acb3a3aac8853eb649c0fb091f01a8f Mon Sep 17 00:00:00 2001 From: Luke Wilde Date: Mon, 26 Dec 2022 00:58:43 +0000 Subject: [PATCH] LibJS: Add yearOfWeek calendar methods and properties This is a normative change in the Temporal spec. See: - https://github.com/tc39/proposal-temporal/commit/7fa4d18 - https://github.com/tc39/proposal-temporal/commit/caa941d --- .../LibJS/Runtime/CommonPropertyNames.h | 1 + .../LibJS/Runtime/Temporal/Calendar.cpp | 87 +++++++++++-------- .../LibJS/Runtime/Temporal/Calendar.h | 9 +- .../Runtime/Temporal/CalendarPrototype.cpp | 47 +++++++--- .../Runtime/Temporal/CalendarPrototype.h | 1 + .../Runtime/Temporal/PlainDatePrototype.cpp | 59 ++++++++----- .../Runtime/Temporal/PlainDatePrototype.h | 1 + .../Temporal/PlainDateTimePrototype.cpp | 65 ++++++++------ .../Runtime/Temporal/PlainDateTimePrototype.h | 1 + .../Temporal/ZonedDateTimePrototype.cpp | 86 +++++++++++------- .../Runtime/Temporal/ZonedDateTimePrototype.h | 1 + .../Calendar/Calendar.prototype.yearOfWeek.js | 19 ++++ .../PlainDate.prototype.yearOfWeek.js | 14 +++ .../PlainDateTime.prototype.yearOfWeek.js | 14 +++ .../ZonedDateTime.prototype.yearOfWeek.js | 15 ++++ 15 files changed, 294 insertions(+), 126 deletions(-) create mode 100644 Userland/Libraries/LibJS/Tests/builtins/Temporal/Calendar/Calendar.prototype.yearOfWeek.js create mode 100644 Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.prototype.yearOfWeek.js create mode 100644 Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.prototype.yearOfWeek.js create mode 100644 Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.yearOfWeek.js diff --git a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h index 0bf153c5d65..8e9301cbeac 100644 --- a/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -573,6 +573,7 @@ namespace JS { P(writable) \ P(year) \ P(yearMonthFromFields) \ + P(yearOfWeek) \ P(years) \ P(yearsDisplay) \ P(zonedDateTime) \ diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index 21437cf1ff8..194920a02d5 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -311,7 +311,22 @@ ThrowCompletionOr calendar_week_of_year(VM& vm, Object& calendar, Object& return TRY(to_positive_integer(vm, result)); } -// 12.2.14 CalendarDaysInWeek ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinweek +// 12.2.15 CalendarYearOfWeek ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendaryearofweek +ThrowCompletionOr calendar_year_of_week(VM& vm, Object& calendar, Object& date_like) +{ + // 1. Let result be ? Invoke(calendar, "yearOfWeek", ยซ dateLike ยป). + auto result = TRY(Value(&calendar).invoke(vm, vm.names.yearOfWeek, &date_like)); + + // 2. If result is undefined, throw a RangeError exception. + if (result.is_undefined()) + return vm.throw_completion(ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.yearOfWeek.as_string(), vm.names.undefined.as_string()); + + // 3. Return ? ToIntegerWithTruncation(result). + // FIXME: ToIntegerThrowOnInfinity was renamed to ToIntegerWithTruncation in https://github.com/tc39/proposal-temporal/commit/f2746783e808c0144f2ce669e004a8c6286f9fc7 + return TRY(to_integer_throw_on_infinity(vm, result, ErrorType::TemporalInvalidCalendarFunctionResult, vm.names.yearOfWeek.as_string(), vm.names.Infinity.to_string())); +} + +// 12.2.16 CalendarDaysInWeek ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinweek ThrowCompletionOr calendar_days_in_week(VM& vm, Object& calendar, Object& date_like) { // 1. Assert: Type(calendar) is Object. @@ -327,7 +342,7 @@ ThrowCompletionOr calendar_days_in_week(VM& vm, Object& calendar, Object& return TRY(to_positive_integer(vm, result)); } -// 12.2.16 CalendarDaysInMonth ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinmonth +// 12.2.17 CalendarDaysInMonth ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinmonth ThrowCompletionOr calendar_days_in_month(VM& vm, Object& calendar, Object& date_like) { // 1. Assert: Type(calendar) is Object. @@ -343,7 +358,7 @@ ThrowCompletionOr calendar_days_in_month(VM& vm, Object& calendar, Object return TRY(to_positive_integer(vm, result)); } -// 12.2.17 CalendarDaysInYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinyear +// 12.2.18 CalendarDaysInYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendardaysinyear ThrowCompletionOr calendar_days_in_year(VM& vm, Object& calendar, Object& date_like) { // 1. Assert: Type(calendar) is Object. @@ -359,7 +374,7 @@ ThrowCompletionOr calendar_days_in_year(VM& vm, Object& calendar, Object& return TRY(to_positive_integer(vm, result)); } -// 12.2.18 CalendarMonthsInYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthsinyear +// 12.2.19 CalendarMonthsInYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthsinyear ThrowCompletionOr calendar_months_in_year(VM& vm, Object& calendar, Object& date_like) { // 1. Assert: Type(calendar) is Object. @@ -375,7 +390,7 @@ ThrowCompletionOr calendar_months_in_year(VM& vm, Object& calendar, Objec return TRY(to_positive_integer(vm, result)); } -// 12.2.29 CalendarInLeapYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarinleapyear +// 12.2.20 CalendarInLeapYear ( calendar, dateLike ), https://tc39.es/proposal-temporal/#sec-temporal-calendarinleapyear ThrowCompletionOr calendar_in_leap_year(VM& vm, Object& calendar, Object& date_like) { // 1. Assert: Type(calendar) is Object. @@ -419,7 +434,7 @@ ThrowCompletionOr calendar_era_year(VM& vm, Object& calendar, Object& dat return result; } -// 12.2.20 ToTemporalCalendar ( temporalCalendarLike ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalcalendar +// 12.2.21 ToTemporalCalendar ( temporalCalendarLike ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalcalendar ThrowCompletionOr to_temporal_calendar(VM& vm, Value temporal_calendar_like) { // 1. If Type(temporalCalendarLike) is Object, then @@ -484,7 +499,7 @@ ThrowCompletionOr to_temporal_calendar(VM& vm, Value temporal_calendar_ return MUST(create_temporal_calendar(vm, identifier)); } -// 12.2.21 ToTemporalCalendarWithISODefault ( temporalCalendarLike ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalcalendarwithisodefault +// 12.2.22 ToTemporalCalendarWithISODefault ( temporalCalendarLike ), https://tc39.es/proposal-temporal/#sec-temporal-totemporalcalendarwithisodefault ThrowCompletionOr to_temporal_calendar_with_iso_default(VM& vm, Value temporal_calendar_like) { // 1. If temporalCalendarLike is undefined, then @@ -496,7 +511,7 @@ ThrowCompletionOr to_temporal_calendar_with_iso_default(VM& vm, Value t return to_temporal_calendar(vm, temporal_calendar_like); } -// 12.2.22 GetTemporalCalendarWithISODefault ( item ), https://tc39.es/proposal-temporal/#sec-temporal-gettemporalcalendarwithisodefault +// 12.2.23 GetTemporalCalendarWithISODefault ( item ), https://tc39.es/proposal-temporal/#sec-temporal-gettemporalcalendarwithisodefault ThrowCompletionOr get_temporal_calendar_with_iso_default(VM& vm, Object& item) { // 1. If item has an [[InitializedTemporalDate]], [[InitializedTemporalDateTime]], [[InitializedTemporalMonthDay]], [[InitializedTemporalTime]], [[InitializedTemporalYearMonth]], or [[InitializedTemporalZonedDateTime]] internal slot, then @@ -521,7 +536,7 @@ ThrowCompletionOr get_temporal_calendar_with_iso_default(VM& vm, Object return to_temporal_calendar_with_iso_default(vm, calendar_like); } -// 12.2.23 CalendarDateFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardatefromfields +// 12.2.24 CalendarDateFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendardatefromfields ThrowCompletionOr calendar_date_from_fields(VM& vm, Object& calendar, Object const& fields, Object const* options) { // 1. If options is not present, set options to undefined. @@ -538,7 +553,7 @@ ThrowCompletionOr calendar_date_from_fields(VM& vm, Object& calendar return static_cast(date_object); } -// 12.2.24 CalendarYearMonthFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendaryearmonthfromfields +// 12.2.25 CalendarYearMonthFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendaryearmonthfromfields ThrowCompletionOr calendar_year_month_from_fields(VM& vm, Object& calendar, Object const& fields, Object const* options) { // 1. If options is not present, set options to undefined. @@ -555,7 +570,7 @@ ThrowCompletionOr calendar_year_month_from_fields(VM& vm, Objec return static_cast(year_month_object); } -// 12.2.25 CalendarMonthDayFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthdayfromfields +// 12.2.26 CalendarMonthDayFromFields ( calendar, fields [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal-calendarmonthdayfromfields ThrowCompletionOr calendar_month_day_from_fields(VM& vm, Object& calendar, Object const& fields, Object const* options) { // 1. If options is not present, set options to undefined. @@ -572,7 +587,7 @@ ThrowCompletionOr calendar_month_day_from_fields(VM& vm, Object& return static_cast(month_day_object); } -// 12.2.26 MaybeFormatCalendarAnnotation ( calendarObject, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-maybeformatcalendarannotation +// 12.2.27 MaybeFormatCalendarAnnotation ( calendarObject, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-maybeformatcalendarannotation ThrowCompletionOr maybe_format_calendar_annotation(VM& vm, Object const* calendar_object, StringView show_calendar) { // 1. If showCalendar is "never", return the empty String. @@ -589,7 +604,7 @@ ThrowCompletionOr maybe_format_calendar_annotation(VM& vm, Obj return format_calendar_annotation(calendar_id, show_calendar); } -// 12.2.27 FormatCalendarAnnotation ( id, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-formatcalendarannotation +// 12.2.28 FormatCalendarAnnotation ( id, showCalendar ), https://tc39.es/proposal-temporal/#sec-temporal-formatcalendarannotation DeprecatedString format_calendar_annotation(StringView id, StringView show_calendar) { VERIFY(show_calendar == "auto"sv || show_calendar == "always"sv || show_calendar == "never"sv || show_calendar == "critical"sv); @@ -609,7 +624,7 @@ DeprecatedString format_calendar_annotation(StringView id, StringView show_calen return DeprecatedString::formatted("[{}u-ca={}]", flag, id); } -// 12.2.28 CalendarEquals ( one, two ), https://tc39.es/proposal-temporal/#sec-temporal-calendarequals +// 12.2.29 CalendarEquals ( one, two ), https://tc39.es/proposal-temporal/#sec-temporal-calendarequals ThrowCompletionOr calendar_equals(VM& vm, Object& one, Object& two) { // 1. If one and two are the same Object value, return true. @@ -630,7 +645,7 @@ ThrowCompletionOr calendar_equals(VM& vm, Object& one, Object& two) return false; } -// 12.2.29 ConsolidateCalendars ( one, two ), https://tc39.es/proposal-temporal/#sec-temporal-consolidatecalendars +// 12.2.30 ConsolidateCalendars ( one, two ), https://tc39.es/proposal-temporal/#sec-temporal-consolidatecalendars ThrowCompletionOr consolidate_calendars(VM& vm, Object& one, Object& two) { // 1. If one and two are the same Object value, return two. @@ -659,7 +674,7 @@ ThrowCompletionOr consolidate_calendars(VM& vm, Object& one, Object& tw return vm.throw_completion(ErrorType::TemporalInvalidCalendar); } -// 12.2.30 ISODaysInMonth ( year, month ), https://tc39.es/proposal-temporal/#sec-temporal-isodaysinmonth +// 12.2.31 ISODaysInMonth ( year, month ), https://tc39.es/proposal-temporal/#sec-temporal-isodaysinmonth u8 iso_days_in_month(i32 year, u8 month) { // 1. Assert: year is an integer. @@ -679,8 +694,8 @@ u8 iso_days_in_month(i32 year, u8 month) return 28 + JS::in_leap_year(time_from_year(year)); } -// 12.2.31 ToISOWeekOfYear ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisoweekofyear -u8 to_iso_week_of_year(i32 year, u8 month, u8 day) +// 12.2.32 ToISOWeekOfYear ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisoweekofyear +YearWeekRecord to_iso_week_of_year(i32 year, u8 month, u8 day) { // 1. Assert: IsValidISODate(year, month, day) is true. VERIFY(is_valid_iso_date(year, month, day)); @@ -721,18 +736,18 @@ u8 to_iso_week_of_year(i32 year, u8 month, u8 day) // c. If dayOfJan1st is friday, then if (day_of_jan_1st == friday) { - // i. Return maxWeekNumber. - return max_week_number; + // i. Return the Year-Week Record { [[Week]]: maxWeekNumber, [[Year]]: year - 1 }. + return YearWeekRecord { .week = max_week_number, .year = year - 1 }; } // d. If dayOfJan1st is saturday, and InLeapYear(TimeFromYear(๐”ฝ(year - 1))) is 1๐”ฝ, then if (day_of_jan_1st == saturday && in_leap_year(time_from_year(year - 1))) { - // i. Return maxWeekNumber. - return max_week_number; + // i. Return the Year-Week Record { [[Week]]: maxWeekNumber. [[Year]]: year - 1 }. + return YearWeekRecord { .week = max_week_number, .year = year - 1 }; } - // e. Return maxWeekNumber - 1. - return max_week_number - 1; + // e. Return the Year-Week Record { [[Week]]: maxWeekNumber - 1, [[Year]]: year - 1 }. + return YearWeekRecord { .week = max_week_number - 1, .year = year - 1 }; } // 12. If week is maxWeekNumber, then @@ -748,16 +763,16 @@ u8 to_iso_week_of_year(i32 year, u8 month, u8 day) // d. If daysLaterInYear < daysAfterThursday, then if (days_later_in_year < days_after_thursday) { - // i. Return 1. - return 1; + // i. Return the Year-Week Record { [[Week]]: 1, [[Year]]: year + 1 }. + return YearWeekRecord { .week = 1, .year = year + 1 }; } } - // 13. Return week. - return week; + // 13. Return the Year-Week Record { [[Week]]: week, [[Year]]: year }. + return YearWeekRecord { .week = static_cast(week), .year = year }; } -// 12.2.32 ISOMonthCode ( month ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthcode +// 12.2.33 ISOMonthCode ( month ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthcode DeprecatedString iso_month_code(u8 month) { // 1. Let numberPart be ToZeroPaddedDecimalString(month, 2). @@ -765,7 +780,7 @@ DeprecatedString iso_month_code(u8 month) return DeprecatedString::formatted("M{:02}", month); } -// 12.2.33 ResolveISOMonth ( fields ), https://tc39.es/proposal-temporal/#sec-temporal-resolveisomonth +// 12.2.34 ResolveISOMonth ( fields ), https://tc39.es/proposal-temporal/#sec-temporal-resolveisomonth ThrowCompletionOr resolve_iso_month(VM& vm, Object const& fields) { // 1. Assert: fields is an ordinary object with no more and no less than the own data properties listed in Table 13. @@ -824,7 +839,7 @@ ThrowCompletionOr resolve_iso_month(VM& vm, Object const& fields) return month_code_number; } -// 12.2.34 ISODateFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isodatefromfields +// 12.2.35 ISODateFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isodatefromfields ThrowCompletionOr iso_date_from_fields(VM& vm, Object const& fields, Object const& options) { // 1. Assert: Type(fields) is Object. @@ -854,7 +869,7 @@ ThrowCompletionOr iso_date_from_fields(VM& vm, Object const& fiel return regulate_iso_date(vm, year.as_double(), month, day.as_double(), overflow); } -// 12.2.35 ISOYearMonthFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isoyearmonthfromfields +// 12.2.36 ISOYearMonthFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isoyearmonthfromfields ThrowCompletionOr iso_year_month_from_fields(VM& vm, Object const& fields, Object const& options) { // 1. Assert: Type(fields) is Object. @@ -881,7 +896,7 @@ ThrowCompletionOr iso_year_month_from_fields(VM& vm, Object const& 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.37 ISOMonthDayFromFields ( fields, options ), https://tc39.es/proposal-temporal/#sec-temporal-isomonthdayfromfields ThrowCompletionOr iso_month_day_from_fields(VM& vm, Object const& fields, Object const& options) { // 1. Assert: Type(fields) is Object. @@ -939,7 +954,7 @@ ThrowCompletionOr iso_month_day_from_fields(VM& vm, Object const& f return ISOMonthDay { .month = result->month, .day = result->day, .reference_iso_year = reference_iso_year }; } -// 12.2.37 DefaultMergeCalendarFields ( fields, additionalFields ), https://tc39.es/proposal-temporal/#sec-temporal-defaultmergecalendarfields +// 12.2.38 DefaultMergeCalendarFields ( fields, additionalFields ), https://tc39.es/proposal-temporal/#sec-temporal-defaultmergecalendarfields ThrowCompletionOr default_merge_calendar_fields(VM& vm, Object const& fields, Object const& additional_fields) { auto& realm = *vm.current_realm(); @@ -1015,7 +1030,7 @@ ThrowCompletionOr default_merge_calendar_fields(VM& vm, Object const& f return merged.ptr(); } -// 12.2.38 ToISODayOfYear ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisodayofyear +// 12.2.39 ToISODayOfYear ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisodayofyear u16 to_iso_day_of_year(i32 year, u8 month, u8 day) { // 1. Assert: IsValidISODate(year, month, day) is true. @@ -1031,7 +1046,7 @@ u16 to_iso_day_of_year(i32 year, u8 month, u8 day) return day_within_year(make_date(epoch_days, 0)) + 1; } -// 12.2.39 ToISODayOfWeek ( year, month, day ), https://tc39.es/proposal-temporal/#sec-temporal-toisodayofweek +// 12.2.40 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: IsValidISODate(year, month, day) is true. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h index 405a1f0a8aa..d0f77921975 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.h @@ -31,6 +31,12 @@ private: DeprecatedString m_identifier; // [[Identifier]] }; +// 14.2 The Year-Week Record Specification Type, https://tc39.es/proposal-temporal/#sec-year-week-record-specification-type +struct YearWeekRecord { + u8 week { 0 }; + i32 year { 0 }; +}; + bool is_builtin_calendar(DeprecatedString const& identifier); Span available_calendars(); ThrowCompletionOr create_temporal_calendar(VM&, DeprecatedString const& identifier, FunctionObject const* new_target = nullptr); @@ -47,6 +53,7 @@ ThrowCompletionOr calendar_day(VM&, Object& calendar, Object& date_like) ThrowCompletionOr calendar_day_of_week(VM&, Object& calendar, Object& date_like); ThrowCompletionOr calendar_day_of_year(VM&, Object& calendar, Object& date_like); ThrowCompletionOr calendar_week_of_year(VM&, Object& calendar, Object& date_like); +ThrowCompletionOr calendar_year_of_week(VM&, Object& calendar, Object& date_like); ThrowCompletionOr calendar_days_in_week(VM&, Object& calendar, Object& date_like); ThrowCompletionOr calendar_days_in_month(VM&, Object& calendar, Object& date_like); ThrowCompletionOr calendar_days_in_year(VM&, Object& calendar, Object& date_like); @@ -65,7 +72,7 @@ DeprecatedString format_calendar_annotation(StringView id, StringView show_calen ThrowCompletionOr calendar_equals(VM&, Object& one, Object& two); ThrowCompletionOr consolidate_calendars(VM&, Object& one, Object& two); u8 iso_days_in_month(i32 year, u8 month); -u8 to_iso_week_of_year(i32 year, u8 month, u8 day); +YearWeekRecord to_iso_week_of_year(i32 year, u8 month, u8 day); DeprecatedString iso_month_code(u8 month); ThrowCompletionOr resolve_iso_month(VM&, Object const& fields); ThrowCompletionOr iso_date_from_fields(VM&, Object const& fields, Object const& options); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp index 81d03f54291..d7611d54316 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.cpp @@ -53,6 +53,7 @@ void CalendarPrototype::initialize(Realm& realm) define_native_function(realm, vm.names.dayOfWeek, day_of_week, 1, attr); define_native_function(realm, vm.names.dayOfYear, day_of_year, 1, attr); define_native_function(realm, vm.names.weekOfYear, week_of_year, 1, attr); + define_native_function(realm, vm.names.yearOfWeek, year_of_week, 1, attr); define_native_function(realm, vm.names.daysInWeek, days_in_week, 1, attr); define_native_function(realm, vm.names.daysInMonth, days_in_month, 1, attr); define_native_function(realm, vm.names.daysInYear, days_in_year, 1, attr); @@ -377,11 +378,35 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::week_of_year) // 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). auto* temporal_date = TRY(to_temporal_date(vm, vm.argument(0))); - // 5. Return ๐”ฝ(ToISODayOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]])). - return Value(to_iso_week_of_year(temporal_date->iso_year(), temporal_date->iso_month(), temporal_date->iso_day())); + // 5. Let isoYearWeek be ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]]). + auto iso_year_week = to_iso_week_of_year(temporal_date->iso_year(), temporal_date->iso_month(), temporal_date->iso_day()); + + // 6. Return ๐”ฝ(isoYearWeek.[[Week]]). + return Value(iso_year_week.week); } -// 12.4.16 Temporal.Calendar.prototype.daysInWeek ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.daysinweek +// 12.5.16 Temporal.Calendar.prototype.yearOfWeek ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.yearofweek +// NOTE: This is the minimum yearOfWeek implementation for engines without ECMA-402. +JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::year_of_week) +{ + // 1. Let calendar be the this value. + // 2. Perform ? RequireInternalSlot(calendar, [[InitializedTemporalCalendar]]). + auto* calendar = TRY(typed_this_object(vm)); + + // 3. Assert: calendar.[[Identifier]] is "iso8601". + VERIFY(calendar->identifier() == "iso8601"sv); + + // 4. Let temporalDate be ? ToTemporalDate(temporalDateLike). + auto* temporal_date = TRY(to_temporal_date(vm, vm.argument(0))); + + // 5. Let isoYearWeek be ToISOWeekOfYear(temporalDate.[[ISOYear]], temporalDate.[[ISOMonth]], temporalDate.[[ISODay]]). + auto iso_year_week = to_iso_week_of_year(temporal_date->iso_year(), temporal_date->iso_month(), temporal_date->iso_day()); + + // 6. Return ๐”ฝ(isoYearWeek.[[Year]]). + return Value(iso_year_week.year); +} + +// 12.4.17 Temporal.Calendar.prototype.daysInWeek ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.daysinweek // NOTE: This is the minimum daysInWeek implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::days_in_week) { @@ -399,7 +424,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::days_in_week) return Value(7); } -// 12.4.16 Temporal.Calendar.prototype.daysInMonth ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.daysinweek +// 12.4.18 Temporal.Calendar.prototype.daysInMonth ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.daysinweek // NOTE: This is the minimum daysInMonth implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::days_in_month) { @@ -421,7 +446,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::days_in_month) return Value(iso_days_in_month(iso_year(temporal_date_like.as_object()), iso_month(temporal_date_like.as_object()))); } -// 12.4.18 Temporal.Calendar.prototype.daysInYear ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.daysinyear +// 12.4.19 Temporal.Calendar.prototype.daysInYear ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.daysinyear // NOTE: This is the minimum daysInYear implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::days_in_year) { @@ -443,7 +468,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::days_in_year) return Value(JS::days_in_year(iso_year(temporal_date_like.as_object()))); } -// 12.4.19 Temporal.Calendar.prototype.monthsInYear ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.monthsinyear +// 12.4.20 Temporal.Calendar.prototype.monthsInYear ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.monthsinyear // NOTE: This is the minimum monthsInYear implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::months_in_year) { @@ -465,7 +490,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::months_in_year) return Value(12); } -// 12.4.20 Temporal.Calendar.prototype.inLeapYear ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.inleapyear +// 12.4.21 Temporal.Calendar.prototype.inLeapYear ( temporalDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.inleapyear // NOTE: This is the minimum inLeapYear implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::in_leap_year) { @@ -491,7 +516,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::in_leap_year) return Value(false); } -// 12.4.21 Temporal.Calendar.prototype.fields ( fields ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.fields +// 12.4.22 Temporal.Calendar.prototype.fields ( fields ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.fields // NOTE: This is the minimum fields implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields) { @@ -560,7 +585,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::fields) return Array::create_from(realm, field_names); } -// 12.4.22 Temporal.Calendar.prototype.mergeFields ( fields, additionalFields ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.mergefields +// 12.4.23 Temporal.Calendar.prototype.mergeFields ( fields, additionalFields ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.mergefields // NOTE: This is the minimum mergeFields implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::merge_fields) { @@ -581,7 +606,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::merge_fields) return TRY(default_merge_calendar_fields(vm, *fields, *additional_fields)); } -// 12.4.23 Temporal.Calendar.prototype.toString ( ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tostring +// 12.4.24 Temporal.Calendar.prototype.toString ( ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tostring JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::to_string) { // 1. Let calendar be the this value. @@ -592,7 +617,7 @@ JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::to_string) return PrimitiveString::create(vm, calendar->identifier()); } -// 12.4.24 Temporal.Calendar.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tojson +// 12.4.25 Temporal.Calendar.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.calendar.prototype.tojson JS_DEFINE_NATIVE_FUNCTION(CalendarPrototype::to_json) { // 1. Let calendar be the this value. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.h b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.h index 317c7ee4264..38cc71dab1e 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/CalendarPrototype.h @@ -34,6 +34,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(day_of_week); JS_DECLARE_NATIVE_FUNCTION(day_of_year); JS_DECLARE_NATIVE_FUNCTION(week_of_year); + JS_DECLARE_NATIVE_FUNCTION(year_of_week); JS_DECLARE_NATIVE_FUNCTION(days_in_week); JS_DECLARE_NATIVE_FUNCTION(days_in_month); JS_DECLARE_NATIVE_FUNCTION(days_in_year); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.cpp index 06ec856482e..01316b387b1 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.cpp @@ -42,6 +42,7 @@ void PlainDatePrototype::initialize(Realm& realm) define_native_accessor(realm, vm.names.dayOfWeek, day_of_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.dayOfYear, day_of_year_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.weekOfYear, week_of_year_getter, {}, Attribute::Configurable); + define_native_accessor(realm, vm.names.yearOfWeek, year_of_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInWeek, days_in_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInMonth, days_in_month_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInYear, days_in_year_getter, {}, Attribute::Configurable); @@ -174,11 +175,25 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::week_of_year_getter) // 3. Let calendar be temporalDate.[[Calendar]]. auto& calendar = temporal_date->calendar(); - // Return ? CalendarWeekOfYear(calendar, temporalDate). + // 4. Return ? CalendarWeekOfYear(calendar, temporalDate). return Value(TRY(calendar_week_of_year(vm, calendar, *temporal_date))); } -// 3.3.11 get Temporal.PlainDate.prototype.daysInWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.daysinweek +// 3.3.11 get Temporal.PlainDate.prototype.yearOfWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.yearofweek +JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::year_of_week_getter) +{ + // 1. Let temporalDate be the this value. + // 2. Perform ? RequireInternalSlot(temporalDate, [[InitializedTemporalDate]]). + auto* temporal_date = TRY(typed_this_object(vm)); + + // 3. Let calendar be temporalDate.[[Calendar]]. + auto& calendar = temporal_date->calendar(); + + // 4. Return ๐”ฝ(? CalendarYearOfWeek(calendar, temporalDate)). + return Value(TRY(calendar_year_of_week(vm, calendar, *temporal_date))); +} + +// 3.3.12 get Temporal.PlainDate.prototype.daysInWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.daysinweek JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::days_in_week_getter) { // 1. Let temporalDate be the this value. @@ -192,7 +207,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::days_in_week_getter) return Value(TRY(calendar_days_in_week(vm, calendar, *temporal_date))); } -// 3.3.12 get Temporal.PlainDate.prototype.daysInMonth, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.daysinmonth +// 3.3.13 get Temporal.PlainDate.prototype.daysInMonth, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.daysinmonth JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::days_in_month_getter) { // 1. Let temporalDate be the this value. @@ -206,7 +221,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::days_in_month_getter) return Value(TRY(calendar_days_in_month(vm, calendar, *temporal_date))); } -// 3.3.13 get Temporal.PlainDate.prototype.daysInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.daysinyear +// 3.3.14 get Temporal.PlainDate.prototype.daysInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.daysinyear JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::days_in_year_getter) { // 1. Let temporalDate be the this value. @@ -220,7 +235,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::days_in_year_getter) return Value(TRY(calendar_days_in_year(vm, calendar, *temporal_date))); } -// 3.3.14 get Temporal.PlainDate.prototype.monthsInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.monthsinyear +// 3.3.15 get Temporal.PlainDate.prototype.monthsInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.monthsinyear JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::months_in_year_getter) { // 1. Let temporalDate be the this value. @@ -234,7 +249,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::months_in_year_getter) return Value(TRY(calendar_months_in_year(vm, calendar, *temporal_date))); } -// 3.3.15 get Temporal.PlainDate.prototype.inLeapYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.inleapyear +// 3.3.16 get Temporal.PlainDate.prototype.inLeapYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindate.prototype.inleapyear JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::in_leap_year_getter) { // 1. Let temporalDate be the this value. @@ -276,7 +291,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::era_year_getter) return TRY(calendar_era_year(vm, calendar, *plain_date)); } -// 3.3.16 Temporal.PlainDate.prototype.toPlainYearMonth ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.toplainyearmonth +// 3.3.17 Temporal.PlainDate.prototype.toPlainYearMonth ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.toplainyearmonth JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_plain_year_month) { // 1. Let temporalDate be the this value. @@ -296,7 +311,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_plain_year_month) return TRY(calendar_year_month_from_fields(vm, calendar, *fields)); } -// 3.3.17 Temporal.PlainDate.prototype.toPlainMonthDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.toplainmonthday +// 3.3.18 Temporal.PlainDate.prototype.toPlainMonthDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.toplainmonthday JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_plain_month_day) { // 1. Let temporalDate be the this value. @@ -316,7 +331,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_plain_month_day) return TRY(calendar_month_day_from_fields(vm, calendar, *fields)); } -// 3.3.18 Temporal.PlainDate.prototype.getISOFields ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.getisofields +// 3.3.19 Temporal.PlainDate.prototype.getISOFields ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.getisofields JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::get_iso_fields) { auto& realm = *vm.current_realm(); @@ -344,7 +359,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::get_iso_fields) return fields; } -// 3.3.19 Temporal.PlainDate.prototype.add ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.add +// 3.3.20 Temporal.PlainDate.prototype.add ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.add JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::add) { // 1. Let temporalDate be the this value. @@ -361,7 +376,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::add) return TRY(calendar_date_add(vm, temporal_date->calendar(), temporal_date, *duration, options)); } -// 3.3.20 Temporal.PlainDate.prototype.subtract ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.subtract +// 3.3.21 Temporal.PlainDate.prototype.subtract ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.subtract JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::subtract) { // 1. Let temporalDate be the this value. @@ -381,7 +396,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::subtract) return TRY(calendar_date_add(vm, temporal_date->calendar(), temporal_date, *negated_duration, options)); } -// 3.3.21 Temporal.PlainDate.prototype.with ( temporalDateLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.with +// 3.3.22 Temporal.PlainDate.prototype.with ( temporalDateLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.with JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::with) { auto temporal_date_like = vm.argument(0); @@ -424,7 +439,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::with) return TRY(calendar_date_from_fields(vm, calendar, *fields, options)); } -// 3.3.22 Temporal.PlainDate.prototype.withCalendar ( calendarLike ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.withcalendar +// 3.3.23 Temporal.PlainDate.prototype.withCalendar ( calendarLike ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.withcalendar JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::with_calendar) { auto calendar_like = vm.argument(0); @@ -440,7 +455,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::with_calendar) return MUST(create_temporal_date(vm, temporal_date->iso_year(), temporal_date->iso_month(), temporal_date->iso_day(), *calendar)); } -// 3.3.23 Temporal.PlainDate.prototype.until ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.until +// 3.3.24 Temporal.PlainDate.prototype.until ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.until JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::until) { auto other = vm.argument(0); @@ -454,7 +469,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::until) return TRY(difference_temporal_plain_date(vm, DifferenceOperation::Until, *temporal_date, other, options)); } -// 3.3.24 Temporal.PlainDate.prototype.since ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.since +// 3.3.25 Temporal.PlainDate.prototype.since ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.since JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::since) { auto other = vm.argument(0); @@ -468,7 +483,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::since) return TRY(difference_temporal_plain_date(vm, DifferenceOperation::Since, *temporal_date, other, options)); } -// 3.3.25 Temporal.PlainDate.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.equals +// 3.3.26 Temporal.PlainDate.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.equals JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::equals) { // 1. Let temporalDate be the this value. @@ -491,7 +506,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::equals) return Value(TRY(calendar_equals(vm, temporal_date->calendar(), other->calendar()))); } -// 3.3.26 Temporal.PlainDate.prototype.toPlainDateTime ( [ temporalTime ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.toplaindatetime +// 3.3.27 Temporal.PlainDate.prototype.toPlainDateTime ( [ temporalTime ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.toplaindatetime JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_plain_date_time) { // 1. Let temporalDate be the this value. @@ -511,7 +526,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_plain_date_time) return TRY(create_temporal_date_time(vm, temporal_date->iso_year(), temporal_date->iso_month(), temporal_date->iso_day(), temporal_time->iso_hour(), temporal_time->iso_minute(), temporal_time->iso_second(), temporal_time->iso_millisecond(), temporal_time->iso_microsecond(), temporal_time->iso_nanosecond(), temporal_date->calendar())); } -// 3.3.27 Temporal.PlainDate.prototype.toZonedDateTime ( item ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tozoneddatetime +// 3.3.28 Temporal.PlainDate.prototype.toZonedDateTime ( item ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tozoneddatetime JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_zoned_date_time) { auto item = vm.argument(0); @@ -585,7 +600,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_zoned_date_time) return MUST(create_temporal_zoned_date_time(vm, instant->nanoseconds(), *time_zone, temporal_date->calendar())); } -// 3.3.28 Temporal.PlainDate.prototype.toString ( [ options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.tostring +// 3.3.29 Temporal.PlainDate.prototype.toString ( [ options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.tostring JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_string) { // 1. Let temporalDate be the this value. @@ -602,7 +617,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_string) return PrimitiveString::create(vm, TRY(temporal_date_to_string(vm, *temporal_date, show_calendar))); } -// 3.3.29 Temporal.PlainDate.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.tolocalestring +// 3.3.30 Temporal.PlainDate.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.tolocalestring // NOTE: This is the minimum toLocaleString implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_locale_string) { @@ -614,7 +629,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_locale_string) return PrimitiveString::create(vm, TRY(temporal_date_to_string(vm, *temporal_date, "auto"sv))); } -// 3.3.30 Temporal.PlainDate.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.tojson +// 3.3.31 Temporal.PlainDate.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.tojson JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_json) { // 1. Let temporalDate be the this value. @@ -625,7 +640,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::to_json) return PrimitiveString::create(vm, TRY(temporal_date_to_string(vm, *temporal_date, "auto"sv))); } -// 3.3.31 Temporal.PlainDate.prototype.valueOf ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.valueof +// 3.3.32 Temporal.PlainDate.prototype.valueOf ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindate.prototype.valueof JS_DEFINE_NATIVE_FUNCTION(PlainDatePrototype::value_of) { // 1. Throw a TypeError exception. diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.h b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.h index 6ffb2dcda24..dd3d45c8371 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDatePrototype.h @@ -29,6 +29,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(day_of_week_getter); JS_DECLARE_NATIVE_FUNCTION(day_of_year_getter); JS_DECLARE_NATIVE_FUNCTION(week_of_year_getter); + JS_DECLARE_NATIVE_FUNCTION(year_of_week_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_week_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_month_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_year_getter); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp index fc167777800..ff7b4689886 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.cpp @@ -49,6 +49,7 @@ void PlainDateTimePrototype::initialize(Realm& realm) define_native_accessor(realm, vm.names.dayOfWeek, day_of_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.dayOfYear, day_of_year_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.weekOfYear, week_of_year_getter, {}, Attribute::Configurable); + define_native_accessor(realm, vm.names.yearOfWeek, year_of_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInWeek, days_in_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInMonth, days_in_month_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInYear, days_in_year_getter, {}, Attribute::Configurable); @@ -255,7 +256,21 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::week_of_year_getter) return TRY(calendar_week_of_year(vm, calendar, *date_time)); } -// 5.3.17 get Temporal.PlainDateTime.prototype.daysInWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.daysinweek +// 5.3.17 get Temporal.PlainDateTime.prototype.yearOfWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.yearofweek +JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::year_of_week_getter) +{ + // 1. Let dateTime be the this value. + // 2. Perform ? RequireInternalSlot(dateTime, [[InitializedTemporalDateTime]]). + auto* date_time = TRY(typed_this_object(vm)); + + // 3. Let calendar be dateTime.[[Calendar]]. + auto& calendar = date_time->calendar(); + + // 4. Return ๐”ฝ(? CalendarYearOfWeek(calendar, dateTime)). + return TRY(calendar_year_of_week(vm, calendar, *date_time)); +} + +// 5.3.18 get Temporal.PlainDateTime.prototype.daysInWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.daysinweek JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::days_in_week_getter) { // 1. Let dateTime be the this value. @@ -269,7 +284,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::days_in_week_getter) return TRY(calendar_days_in_week(vm, calendar, *date_time)); } -// 5.3.18 get Temporal.PlainDateTime.prototype.daysInMonth, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.daysinmonth +// 5.3.19 get Temporal.PlainDateTime.prototype.daysInMonth, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.daysinmonth JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::days_in_month_getter) { // 1. Let dateTime be the this value. @@ -283,7 +298,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::days_in_month_getter) return TRY(calendar_days_in_month(vm, calendar, *date_time)); } -// 5.3.19 get Temporal.PlainDateTime.prototype.daysInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.daysinyear +// 5.3.20 get Temporal.PlainDateTime.prototype.daysInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.daysinyear JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::days_in_year_getter) { // 1. Let dateTime be the this value. @@ -297,7 +312,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::days_in_year_getter) return TRY(calendar_days_in_year(vm, calendar, *date_time)); } -// 5.3.20 get Temporal.PlainDateTime.prototype.monthsInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.monthsinyear +// 5.3.21 get Temporal.PlainDateTime.prototype.monthsInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.monthsinyear JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::months_in_year_getter) { // 1. Let dateTime be the this value. @@ -311,7 +326,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::months_in_year_getter) return TRY(calendar_months_in_year(vm, calendar, *date_time)); } -// 5.3.21 get Temporal.PlainDateTime.prototype.inLeapYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.inleapyear +// 5.3.22 get Temporal.PlainDateTime.prototype.inLeapYear, https://tc39.es/proposal-temporal/#sec-get-temporal.plaindatetime.prototype.inleapyear JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::in_leap_year_getter) { // 1. Let dateTime be the this value. @@ -353,7 +368,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::era_year_getter) return TRY(calendar_era_year(vm, calendar, *plain_date_time)); } -// 5.3.22 Temporal.PlainDateTime.prototype.with ( temporalDateTimeLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.with +// 5.3.23 Temporal.PlainDateTime.prototype.with ( temporalDateTimeLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.with JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with) { auto temporal_date_time_like = vm.argument(0); @@ -405,7 +420,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with) return TRY(create_temporal_date_time(vm, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, calendar)); } -// 5.3.23 Temporal.PlainDateTime.prototype.withPlainTime ( [ plainTimeLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.withplaintime +// 5.3.24 Temporal.PlainDateTime.prototype.withPlainTime ( [ plainTimeLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.withplaintime JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with_plain_time) { // 1. Let dateTime be the this value. @@ -425,7 +440,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with_plain_time) return TRY(create_temporal_date_time(vm, date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), plain_time->iso_hour(), plain_time->iso_minute(), plain_time->iso_second(), plain_time->iso_millisecond(), plain_time->iso_microsecond(), plain_time->iso_nanosecond(), date_time->calendar())); } -// 5.3.24 Temporal.PlainDateTime.prototype.withPlainDate ( plainDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.withplaindate +// 5.3.25 Temporal.PlainDateTime.prototype.withPlainDate ( plainDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.withplaindate JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with_plain_date) { // 1. Let dateTime be the this value. @@ -442,7 +457,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with_plain_date) return TRY(create_temporal_date_time(vm, plain_date->iso_year(), plain_date->iso_month(), plain_date->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(), *calendar)); } -// 5.3.25 Temporal.PlainDateTime.prototype.withCalendar ( calendarLike ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.withcalendar +// 5.3.26 Temporal.PlainDateTime.prototype.withCalendar ( calendarLike ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.withcalendar JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with_calendar) { auto calendar_like = vm.argument(0); @@ -458,7 +473,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::with_calendar) return TRY(create_temporal_date_time(vm, 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(), *calendar)); } -// 5.3.26 Temporal.PlainDateTime.prototype.add ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.add +// 5.3.27 Temporal.PlainDateTime.prototype.add ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.add JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::add) { auto temporal_duration_like = vm.argument(0); @@ -472,7 +487,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::add) return TRY(add_duration_to_or_subtract_duration_from_plain_date_time(vm, ArithmeticOperation::Add, *date_time, temporal_duration_like, options)); } -// 5.3.27 Temporal.PlainDateTime.prototype.subtract ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.subtract +// 5.3.28 Temporal.PlainDateTime.prototype.subtract ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.subtract JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::subtract) { auto temporal_duration_like = vm.argument(0); @@ -486,7 +501,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::subtract) return TRY(add_duration_to_or_subtract_duration_from_plain_date_time(vm, ArithmeticOperation::Subtract, *date_time, temporal_duration_like, options)); } -// 5.3.28 Temporal.PlainDateTime.prototype.until ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime.prototype.since +// 5.3.29 Temporal.PlainDateTime.prototype.until ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaintime.prototype.since JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::until) { auto other = vm.argument(0); @@ -500,7 +515,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::until) return TRY(difference_temporal_plain_date_time(vm, DifferenceOperation::Until, *date_time, other, options)); } -// 5.3.29 Temporal.PlainDateTime.prototype.since ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.since +// 5.3.30 Temporal.PlainDateTime.prototype.since ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.since JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::since) { auto other = vm.argument(0); @@ -514,7 +529,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::since) return TRY(difference_temporal_plain_date_time(vm, DifferenceOperation::Since, *date_time, other, options)); } -// 5.3.30 Temporal.PlainDateTime.prototype.round ( roundTo ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.round +// 5.3.31 Temporal.PlainDateTime.prototype.round ( roundTo ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.round JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::round) { auto& realm = *vm.current_realm(); @@ -563,7 +578,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::round) return TRY(create_temporal_date_time(vm, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, date_time->calendar())); } -// 5.3.31 Temporal.PlainDateTime.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.equals +// 5.3.32 Temporal.PlainDateTime.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.equals JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::equals) { // 1. Let dateTime be the this value. @@ -584,7 +599,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::equals) return Value(TRY(calendar_equals(vm, date_time->calendar(), other->calendar()))); } -// 5.3.32 Temporal.PlainDateTime.prototype.toString ( [ options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tostring +// 5.3.33 Temporal.PlainDateTime.prototype.toString ( [ options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tostring JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_string) { // 1. Let dateTime be the this value. @@ -610,7 +625,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_string) return PrimitiveString::create(vm, TRY(temporal_date_time_to_string(vm, result.year, result.month, result.day, result.hour, result.minute, result.second, result.millisecond, result.microsecond, result.nanosecond, &date_time->calendar(), precision.precision, show_calendar))); } -// 5.3.33 Temporal.PlainDateTime.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tolocalestring +// 5.3.34 Temporal.PlainDateTime.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tolocalestring // NOTE: This is the minimum toLocaleString implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_locale_string) { @@ -622,7 +637,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_locale_string) return PrimitiveString::create(vm, TRY(temporal_date_time_to_string(vm, 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(), &date_time->calendar(), "auto"sv, "auto"sv))); } -// 5.3.34 Temporal.PlainDateTime.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tojson +// 5.3.35 Temporal.PlainDateTime.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tojson JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_json) { // 1. Let dateTime be the this value. @@ -633,14 +648,14 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_json) return PrimitiveString::create(vm, TRY(temporal_date_time_to_string(vm, 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(), &date_time->calendar(), "auto"sv, "auto"sv))); } -// 5.3.35 Temporal.PlainDateTime.prototype.valueOf ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.valueof +// 5.3.36 Temporal.PlainDateTime.prototype.valueOf ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.valueof JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::value_of) { // 1. Throw a TypeError exception. return vm.throw_completion(ErrorType::Convert, "Temporal.PlainDateTime", "a primitive value"); } -// 5.3.36 Temporal.PlainDateTime.prototype.toZonedDateTime ( temporalTimeZoneLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tozoneddatetime +// 5.3.37 Temporal.PlainDateTime.prototype.toZonedDateTime ( temporalTimeZoneLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.tozoneddatetime JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_zoned_date_time) { // 1. Let dateTime be the this value. @@ -663,7 +678,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_zoned_date_time) return MUST(create_temporal_zoned_date_time(vm, instant->nanoseconds(), *time_zone, date_time->calendar())); } -// 5.3.37 Temporal.PlainDateTime.prototype.toPlainDate ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplaindate +// 5.3.38 Temporal.PlainDateTime.prototype.toPlainDate ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplaindate JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_date) { // 1. Let dateTime be the this value. @@ -674,7 +689,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_date) return MUST(create_temporal_date(vm, date_time->iso_year(), date_time->iso_month(), date_time->iso_day(), date_time->calendar())); } -// 5.3.38 Temporal.PlainDateTime.prototype.toPlainYearMonth ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplainyearmonth +// 5.3.39 Temporal.PlainDateTime.prototype.toPlainYearMonth ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplainyearmonth JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_year_month) { // 1. Let dateTime be the this value. @@ -694,7 +709,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_year_month) return TRY(calendar_year_month_from_fields(vm, calendar, *fields)); } -// 5.3.39 Temporal.PlainDateTime.prototype.toPlainMonthDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplainmonthday +// 5.3.40 Temporal.PlainDateTime.prototype.toPlainMonthDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplainmonthday JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_month_day) { // 1. Let dateTime be the this value. @@ -714,7 +729,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_month_day) return TRY(calendar_month_day_from_fields(vm, calendar, *fields)); } -// 5.3.40 Temporal.PlainDateTime.prototype.toPlainTime ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplaintime +// 5.3.41 Temporal.PlainDateTime.prototype.toPlainTime ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.toplaintime JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_time) { // 1. Let dateTime be the this value. @@ -725,7 +740,7 @@ JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::to_plain_time) return MUST(create_temporal_time(vm, date_time->iso_hour(), date_time->iso_minute(), date_time->iso_second(), date_time->iso_millisecond(), date_time->iso_microsecond(), date_time->iso_nanosecond())); } -// 5.3.41 Temporal.PlainDateTime.prototype.getISOFields ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.getisofields +// 5.3.42 Temporal.PlainDateTime.prototype.getISOFields ( ), https://tc39.es/proposal-temporal/#sec-temporal.plaindatetime.prototype.getisofields JS_DEFINE_NATIVE_FUNCTION(PlainDateTimePrototype::get_iso_fields) { auto& realm = *vm.current_realm(); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.h b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.h index f290e18f39b..b657fa55e43 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateTimePrototype.h @@ -35,6 +35,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(day_of_week_getter); JS_DECLARE_NATIVE_FUNCTION(day_of_year_getter); JS_DECLARE_NATIVE_FUNCTION(week_of_year_getter); + JS_DECLARE_NATIVE_FUNCTION(year_of_week_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_week_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_month_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_year_getter); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp index d545919622f..3e3a26b0dcb 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.cpp @@ -54,6 +54,7 @@ void ZonedDateTimePrototype::initialize(Realm& realm) define_native_accessor(realm, vm.names.dayOfWeek, day_of_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.dayOfYear, day_of_year_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.weekOfYear, week_of_year_getter, {}, Attribute::Configurable); + define_native_accessor(realm, vm.names.yearOfWeek, year_of_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.hoursInDay, hours_in_day_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInWeek, days_in_week_getter, {}, Attribute::Configurable); define_native_accessor(realm, vm.names.daysInMonth, days_in_month_getter, {}, Attribute::Configurable); @@ -474,7 +475,30 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::week_of_year_getter) return TRY(calendar_week_of_year(vm, calendar, *temporal_date_time)); } -// 6.3.22 get Temporal.ZonedDateTime.prototype.hoursInDay, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.hoursinday +// 6.3.22 get Temporal.ZonedDateTime.prototype.yearOfWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.yearofweek +JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::year_of_week_getter) +{ + // 1. Let zonedDateTime be the this value. + // 2. Perform ? RequireInternalSlot(zonedDateTime, [[InitializedTemporalZonedDateTime]]). + auto* zoned_date_time = TRY(typed_this_object(vm)); + + // 3. Let timeZone be zonedDateTime.[[TimeZone]]. + auto& time_zone = zoned_date_time->time_zone(); + + // 4. Let instant be ! CreateTemporalInstant(zonedDateTime.[[Nanoseconds]]). + auto* instant = MUST(create_temporal_instant(vm, zoned_date_time->nanoseconds())); + + // 5. Let calendar be zonedDateTime.[[Calendar]]. + auto& calendar = zoned_date_time->calendar(); + + // 6. Let temporalDateTime be ? BuiltinTimeZoneGetPlainDateTimeFor(timeZone, instant, calendar). + auto* temporal_date_time = TRY(builtin_time_zone_get_plain_date_time_for(vm, &time_zone, *instant, calendar)); + + // 7. Return ๐”ฝ(? CalendarYearOfWeek(calendar, temporalDateTime)). + return TRY(calendar_year_of_week(vm, calendar, *temporal_date_time)); +} + +// 6.3.23 get Temporal.ZonedDateTime.prototype.hoursInDay, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.hoursinday JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::hours_in_day_getter) { // 1. Let zonedDateTime be the this value. @@ -525,7 +549,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::hours_in_day_getter) return Value(hours_diff_ns.to_double()); } -// 6.3.23 get Temporal.ZonedDateTime.prototype.daysInWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.daysinweek +// 6.3.24 get Temporal.ZonedDateTime.prototype.daysInWeek, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.daysinweek JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::days_in_week_getter) { // 1. Let zonedDateTime be the this value. @@ -548,7 +572,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::days_in_week_getter) return TRY(calendar_days_in_week(vm, calendar, *temporal_date_time)); } -// 6.3.24 get Temporal.ZonedDateTime.prototype.daysInMonth, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.daysinmonth +// 6.3.25 get Temporal.ZonedDateTime.prototype.daysInMonth, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.daysinmonth JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::days_in_month_getter) { // 1. Let zonedDateTime be the this value. @@ -571,7 +595,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::days_in_month_getter) return TRY(calendar_days_in_month(vm, calendar, *temporal_date_time)); } -// 6.3.25 get Temporal.ZonedDateTime.prototype.daysInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.daysinyear +// 6.3.26 get Temporal.ZonedDateTime.prototype.daysInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.daysinyear JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::days_in_year_getter) { // 1. Let zonedDateTime be the this value. @@ -594,7 +618,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::days_in_year_getter) return TRY(calendar_days_in_year(vm, calendar, *temporal_date_time)); } -// 6.3.26 get Temporal.ZonedDateTime.prototype.monthsInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.monthsinyear +// 6.3.27 get Temporal.ZonedDateTime.prototype.monthsInYear, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.monthsinyear JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::months_in_year_getter) { // 1. Let zonedDateTime be the this value. @@ -617,7 +641,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::months_in_year_getter) return TRY(calendar_months_in_year(vm, calendar, *temporal_date_time)); } -// 6.3.27 get Temporal.ZonedDateTime.prototype.inLeapYear, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.inleapyear +// 6.3.28 get Temporal.ZonedDateTime.prototype.inLeapYear, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.inleapyear JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::in_leap_year_getter) { // 1. Let zonedDateTime be the this value. @@ -640,7 +664,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::in_leap_year_getter) return TRY(calendar_in_leap_year(vm, calendar, *temporal_date_time)); } -// 6.3.28 get Temporal.ZonedDateTime.prototype.offsetNanoseconds, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.offsetnanoseconds +// 6.3.29 get Temporal.ZonedDateTime.prototype.offsetNanoseconds, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.offsetnanoseconds JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::offset_nanoseconds_getter) { // 1. Let zonedDateTime be the this value. @@ -657,7 +681,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::offset_nanoseconds_getter) return Value(TRY(get_offset_nanoseconds_for(vm, &time_zone, *instant))); } -// 6.3.29 get Temporal.ZonedDateTime.prototype.offset, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.offset +// 6.3.30 get Temporal.ZonedDateTime.prototype.offset, https://tc39.es/proposal-temporal/#sec-get-temporal.zoneddatetime.prototype.offset JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::offset_getter) { // 1. Let zonedDateTime be the this value. @@ -718,7 +742,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::era_year_getter) return TRY(calendar_era_year(vm, calendar, *plain_date_time)); } -// 6.3.30 Temporal.ZonedDateTime.prototype.with ( temporalZonedDateTimeLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.with +// 6.3.31 Temporal.ZonedDateTime.prototype.with ( temporalZonedDateTimeLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.with JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with) { auto temporal_zoned_date_time_like = vm.argument(0); @@ -796,7 +820,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with) return MUST(create_temporal_zoned_date_time(vm, *epoch_nanoseconds, time_zone, calendar)); } -// 6.3.31 Temporal.ZonedDateTime.prototype.withPlainTime ( [ plainTimeLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withplaintime +// 6.3.32 Temporal.ZonedDateTime.prototype.withPlainTime ( [ plainTimeLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withplaintime JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_plain_time) { // 1. Let zonedDateTime be the this value. @@ -838,7 +862,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_plain_time) return MUST(create_temporal_zoned_date_time(vm, instant->nanoseconds(), time_zone, calendar)); } -// 6.3.32 Temporal.ZonedDateTime.prototype.withPlainDate ( plainDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withplaindate +// 6.3.33 Temporal.ZonedDateTime.prototype.withPlainDate ( plainDateLike ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withplaindate JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_plain_date) { // 1. Let zonedDateTime be the this value. @@ -870,7 +894,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_plain_date) return MUST(create_temporal_zoned_date_time(vm, instant->nanoseconds(), time_zone, *calendar)); } -// 6.3.33 Temporal.ZonedDateTime.prototype.withTimeZone ( timeZoneLike ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withtimezone +// 6.3.34 Temporal.ZonedDateTime.prototype.withTimeZone ( timeZoneLike ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withtimezone JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_time_zone) { // 1. Let zonedDateTime be the this value. @@ -884,7 +908,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_time_zone) return MUST(create_temporal_zoned_date_time(vm, zoned_date_time->nanoseconds(), *time_zone, zoned_date_time->calendar())); } -// 6.3.34 Temporal.ZonedDateTime.prototype.withCalendar ( calendarLike ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withcalendar +// 6.3.35 Temporal.ZonedDateTime.prototype.withCalendar ( calendarLike ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.withcalendar JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_calendar) { // 1. Let zonedDateTime be the this value. @@ -898,7 +922,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::with_calendar) return MUST(create_temporal_zoned_date_time(vm, zoned_date_time->nanoseconds(), zoned_date_time->time_zone(), *calendar)); } -// 6.3.35 Temporal.ZonedDateTime.prototype.add ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.add +// 6.3.36 Temporal.ZonedDateTime.prototype.add ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.add JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::add) { auto temporal_duration_like = vm.argument(0); @@ -912,7 +936,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::add) return TRY(add_duration_to_or_subtract_duration_from_zoned_date_time(vm, ArithmeticOperation::Add, *zoned_date_time, temporal_duration_like, options)); } -// 6.3.36 Temporal.ZonedDateTime.prototype.subtract ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.subtract +// 6.3.37 Temporal.ZonedDateTime.prototype.subtract ( temporalDurationLike [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.subtract JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::subtract) { auto temporal_duration_like = vm.argument(0); @@ -926,7 +950,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::subtract) return TRY(add_duration_to_or_subtract_duration_from_zoned_date_time(vm, ArithmeticOperation::Subtract, *zoned_date_time, temporal_duration_like, options)); } -// 6.3.37 Temporal.ZonedDateTime.prototype.until ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.until +// 6.3.38 Temporal.ZonedDateTime.prototype.until ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.until JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::until) { auto other = vm.argument(0); @@ -940,7 +964,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::until) return TRY(difference_temporal_zoned_date_time(vm, DifferenceOperation::Until, *zoned_date_time, other, options)); } -// 6.3.38 Temporal.ZonedDateTime.prototype.since ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.since +// 6.3.39 Temporal.ZonedDateTime.prototype.since ( other [ , options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.since JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::since) { auto other = vm.argument(0); @@ -954,7 +978,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::since) return TRY(difference_temporal_zoned_date_time(vm, DifferenceOperation::Since, *zoned_date_time, other, options)); } -// 6.3.39 Temporal.ZonedDateTime.prototype.round ( roundTo ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.round +// 6.3.40 Temporal.ZonedDateTime.prototype.round ( roundTo ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.round JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::round) { auto& realm = *vm.current_realm(); @@ -1045,7 +1069,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::round) return MUST(create_temporal_zoned_date_time(vm, *epoch_nanoseconds, time_zone, calendar)); } -// 6.3.40 Temporal.ZonedDateTime.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.equals +// 6.3.41 Temporal.ZonedDateTime.prototype.equals ( other ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.equals JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::equals) { // 1. Let zonedDateTime be the this value. @@ -1067,7 +1091,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::equals) return Value(TRY(calendar_equals(vm, zoned_date_time->calendar(), other->calendar()))); } -// 6.3.41 Temporal.ZonedDateTime.prototype.toString ( [ options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.tostring +// 6.3.42 Temporal.ZonedDateTime.prototype.toString ( [ options ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.tostring JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_string) { // 1. Let zonedDateTime be the this value. @@ -1096,7 +1120,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_string) return PrimitiveString::create(vm, TRY(temporal_zoned_date_time_to_string(vm, *zoned_date_time, precision.precision, show_calendar, show_time_zone, show_offset, precision.increment, precision.unit, rounding_mode))); } -// 6.3.42 Temporal.ZonedDateTime.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.tolocalestring +// 6.3.43 Temporal.ZonedDateTime.prototype.toLocaleString ( [ locales [ , options ] ] ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.tolocalestring // NOTE: This is the minimum toLocaleString implementation for engines without ECMA-402. JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_locale_string) { @@ -1108,7 +1132,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_locale_string) return PrimitiveString::create(vm, TRY(temporal_zoned_date_time_to_string(vm, *zoned_date_time, "auto"sv, "auto"sv, "auto"sv, "auto"sv))); } -// 6.3.43 Temporal.ZonedDateTime.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.tojson +// 6.3.44 Temporal.ZonedDateTime.prototype.toJSON ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.tojson JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_json) { // 1. Let zonedDateTime be the this value. @@ -1119,14 +1143,14 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_json) return PrimitiveString::create(vm, TRY(temporal_zoned_date_time_to_string(vm, *zoned_date_time, "auto"sv, "auto"sv, "auto"sv, "auto"sv))); } -// 6.3.44 Temporal.ZonedDateTime.prototype.valueOf ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.valueof +// 6.3.45 Temporal.ZonedDateTime.prototype.valueOf ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.valueof JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::value_of) { // 1. Throw a TypeError exception. return vm.throw_completion(ErrorType::Convert, "Temporal.ZonedDateTime", "a primitive value"); } -// 6.3.45 Temporal.ZonedDateTime.prototype.startOfDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.startofday +// 6.3.46 Temporal.ZonedDateTime.prototype.startOfDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.startofday JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::start_of_day) { // 1. Let zonedDateTime be the this value. @@ -1155,7 +1179,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::start_of_day) return MUST(create_temporal_zoned_date_time(vm, start_instant->nanoseconds(), time_zone, calendar)); } -// 6.3.46 Temporal.ZonedDateTime.prototype.toInstant ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toinstant +// 6.3.47 Temporal.ZonedDateTime.prototype.toInstant ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toinstant JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_instant) { // 1. Let zonedDateTime be the this value. @@ -1166,7 +1190,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_instant) return MUST(create_temporal_instant(vm, zoned_date_time->nanoseconds())); } -// 6.3.47 Temporal.ZonedDateTime.prototype.toPlainDate ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplaindate +// 6.3.48 Temporal.ZonedDateTime.prototype.toPlainDate ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplaindate JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_date) { // 1. Let zonedDateTime be the this value. @@ -1189,7 +1213,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_date) return MUST(create_temporal_date(vm, temporal_date_time->iso_year(), temporal_date_time->iso_month(), temporal_date_time->iso_day(), calendar)); } -// 6.3.48 Temporal.ZonedDateTime.prototype.toPlainTime ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplaintime +// 6.3.49 Temporal.ZonedDateTime.prototype.toPlainTime ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplaintime JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_time) { // 1. Let zonedDateTime be the this value. @@ -1212,7 +1236,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_time) return MUST(create_temporal_time(vm, temporal_date_time->iso_hour(), temporal_date_time->iso_minute(), temporal_date_time->iso_second(), temporal_date_time->iso_millisecond(), temporal_date_time->iso_microsecond(), temporal_date_time->iso_nanosecond())); } -// 6.3.49 Temporal.ZonedDateTime.prototype.toPlainDateTime ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplaindatetime +// 6.3.50 Temporal.ZonedDateTime.prototype.toPlainDateTime ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplaindatetime JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_date_time) { // 1. Let zonedDateTime be the this value. @@ -1229,7 +1253,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_date_time) return TRY(builtin_time_zone_get_plain_date_time_for(vm, &time_zone, *instant, zoned_date_time->calendar())); } -// 6.3.50 Temporal.ZonedDateTime.prototype.toPlainYearMonth ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplainyearmonth +// 6.3.51 Temporal.ZonedDateTime.prototype.toPlainYearMonth ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplainyearmonth JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_year_month) { // 1. Let zonedDateTime be the this value. @@ -1258,7 +1282,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_year_month) return TRY(calendar_year_month_from_fields(vm, calendar, *fields)); } -// 6.3.51 Temporal.ZonedDateTime.prototype.toPlainMonthDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplainmonthday +// 6.3.52 Temporal.ZonedDateTime.prototype.toPlainMonthDay ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.toplainmonthday JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_month_day) { // 1. Let zonedDateTime be the this value. @@ -1287,7 +1311,7 @@ JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::to_plain_month_day) return TRY(calendar_month_day_from_fields(vm, calendar, *fields)); } -// 6.3.52 Temporal.ZonedDateTime.prototype.getISOFields ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.getisofields +// 6.3.53 Temporal.ZonedDateTime.prototype.getISOFields ( ), https://tc39.es/proposal-temporal/#sec-temporal.zoneddatetime.prototype.getisofields JS_DEFINE_NATIVE_FUNCTION(ZonedDateTimePrototype::get_iso_fields) { auto& realm = *vm.current_realm(); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.h b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.h index 86bb929a525..4e928774480 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/ZonedDateTimePrototype.h @@ -40,6 +40,7 @@ private: JS_DECLARE_NATIVE_FUNCTION(day_of_week_getter); JS_DECLARE_NATIVE_FUNCTION(day_of_year_getter); JS_DECLARE_NATIVE_FUNCTION(week_of_year_getter); + JS_DECLARE_NATIVE_FUNCTION(year_of_week_getter); JS_DECLARE_NATIVE_FUNCTION(hours_in_day_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_week_getter); JS_DECLARE_NATIVE_FUNCTION(days_in_month_getter); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/Calendar/Calendar.prototype.yearOfWeek.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Calendar/Calendar.prototype.yearOfWeek.js new file mode 100644 index 00000000000..e4aae55756a --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/Calendar/Calendar.prototype.yearOfWeek.js @@ -0,0 +1,19 @@ +describe("correct behavior", () => { + test("length is 1", () => { + expect(Temporal.Calendar.prototype.yearOfWeek).toHaveLength(1); + }); + + test("basic functionality", () => { + const calendar = new Temporal.Calendar("iso8601"); + const date = new Temporal.PlainDate(2023, 1, 1); + expect(calendar.yearOfWeek(date)).toBe(2022); + }); +}); + +describe("errors", () => { + test("this value must be a Temporal.Calendar object", () => { + expect(() => { + Temporal.Calendar.prototype.yearOfWeek.call("foo"); + }).toThrowWithMessage(TypeError, "Not an object of type Temporal.Calendar"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.prototype.yearOfWeek.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.prototype.yearOfWeek.js new file mode 100644 index 00000000000..ab42d277914 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.prototype.yearOfWeek.js @@ -0,0 +1,14 @@ +describe("correct behavior", () => { + test("basic functionality", () => { + const date = new Temporal.PlainDate(2023, 1, 1); + expect(date.yearOfWeek).toBe(2022); + }); +}); + +describe("errors", () => { + test("this value must be a Temporal.PlainDate object", () => { + expect(() => { + Reflect.get(Temporal.PlainDate.prototype, "yearOfWeek", "foo"); + }).toThrowWithMessage(TypeError, "Not an object of type Temporal.PlainDate"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.prototype.yearOfWeek.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.prototype.yearOfWeek.js new file mode 100644 index 00000000000..e733bb6b26e --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDateTime/PlainDateTime.prototype.yearOfWeek.js @@ -0,0 +1,14 @@ +describe("correct behavior", () => { + test("basic functionality", () => { + const plainDateTime = new Temporal.PlainDateTime(2023, 1, 1); + expect(plainDateTime.yearOfWeek).toBe(2022); + }); +}); + +describe("errors", () => { + test("this value must be a Temporal.PlainDateTime object", () => { + expect(() => { + Reflect.get(Temporal.PlainDateTime.prototype, "yearOfWeek", "foo"); + }).toThrowWithMessage(TypeError, "Not an object of type Temporal.PlainDateTime"); + }); +}); diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.yearOfWeek.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.yearOfWeek.js new file mode 100644 index 00000000000..33379a9e857 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/ZonedDateTime/ZonedDateTime.prototype.yearOfWeek.js @@ -0,0 +1,15 @@ +describe("correct behavior", () => { + test("basic functionality", () => { + const timeZone = new Temporal.TimeZone("UTC"); + const zonedDateTime = new Temporal.ZonedDateTime(1672531200000000000n, timeZone); + expect(zonedDateTime.yearOfWeek).toBe(2022); + }); +}); + +describe("errors", () => { + test("this value must be a Temporal.ZonedDateTime object", () => { + expect(() => { + Reflect.get(Temporal.ZonedDateTime.prototype, "yearOfWeek", "foo"); + }).toThrowWithMessage(TypeError, "Not an object of type Temporal.ZonedDateTime"); + }); +});