diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp index 35dad3677c..94e4e506c3 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.cpp @@ -220,4 +220,37 @@ bool is_valid_iso_date(i32 year, u8 month, u8 day) return true; } +// 3.5.10 CompareISODate ( y1, m1, d1, y2, m2, d2 ), https://tc39.es/proposal-temporal/#sec-temporal-compareisodate +i8 compare_iso_date(i32 year1, u8 month1, u8 day1, i32 year2, u8 month2, u8 day2) +{ + // 1. Assert: y1, m1, d1, y2, m2, and d2 are integers. + + // 2. If y1 > y2, return 1. + if (year1 > year2) + return 1; + + // 3. If y1 < y2, return -1. + if (year1 < year2) + return -1; + + // 4. If m1 > m2, return 1. + if (month1 > month2) + return 1; + + // 5. If m1 < m2, return -1. + if (month1 < month2) + return -1; + + // 6. If d1 > d2, return 1. + if (day1 > day2) + return 1; + + // 7. If d1 < d2, return -1. + if (day1 < day2) + return -1; + + // 8. Return 0. + return 0; +} + } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.h b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.h index abc49edfca..aca9a99fbe 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDate.h @@ -38,5 +38,6 @@ PlainDate* create_temporal_date(GlobalObject&, i32 iso_year, u8 iso_month, u8 is PlainDate* to_temporal_date(GlobalObject&, Value item, Object* options = nullptr); Optional regulate_iso_date(GlobalObject&, double year, double month, double day, String const& overflow); bool is_valid_iso_date(i32 year, u8 month, u8 day); +i8 compare_iso_date(i32 year1, u8 month1, u8 day1, i32 year2, u8 month2, u8 day2); } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp index 1e5e056dae..b6f38b2d6b 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.cpp @@ -27,6 +27,9 @@ void PlainDateConstructor::initialize(GlobalObject& global_object) // 3.2.1 Temporal.PlainDate.prototype, https://tc39.es/proposal-temporal/#sec-temporal-plaindate-prototype define_direct_property(vm.names.prototype, global_object.temporal_plain_date_prototype(), 0); + u8 attr = Attribute::Writable | Attribute::Configurable; + define_native_function(vm.names.compare, compare, 2, attr); + define_direct_property(vm.names.length, Value(3), Attribute::Configurable); } @@ -93,4 +96,19 @@ Value PlainDateConstructor::construct(FunctionObject& new_target) return create_temporal_date(global_object, y, m, d, *calendar, &new_target); } +// 3.2.3 Temporal.PlainDate.compare ( one, two ), https://tc39.es/proposal-temporal/#sec-properties-of-the-temporal-plaindate-constructor +JS_DEFINE_NATIVE_FUNCTION(PlainDateConstructor::compare) +{ + // 1. Set one to ? ToTemporalDate(one). + auto* one = to_temporal_date(global_object, vm.argument(0)); + if (vm.exception()) + return {}; + // 2. Set two to ? ToTemporalDate(two). + auto* two = to_temporal_date(global_object, vm.argument(1)); + if (vm.exception()) + return {}; + // 3. Return 𝔽(! CompareISODate(one.[[ISOYear]], one.[[ISOMonth]], one.[[ISODay]], two.[[ISOYear]], two.[[ISOMonth]], two.[[ISODay]])). + return Value(compare_iso_date(one->iso_year(), one->iso_month(), one->iso_day(), two->iso_year(), two->iso_month(), two->iso_day())); +} + } diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h index 830330412d..e02a3153c4 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h +++ b/Userland/Libraries/LibJS/Runtime/Temporal/PlainDateConstructor.h @@ -23,6 +23,8 @@ public: private: virtual bool has_constructor() const override { return true; } + + JS_DECLARE_NATIVE_FUNCTION(compare); }; } diff --git a/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.compare.js b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.compare.js new file mode 100644 index 0000000000..a6a92799a3 --- /dev/null +++ b/Userland/Libraries/LibJS/Tests/builtins/Temporal/PlainDate/PlainDate.compare.js @@ -0,0 +1,13 @@ +describe("correct behavior", () => { + test("length is 2", () => { + expect(Temporal.PlainDate.compare).toHaveLength(2); + }); + + test("basic functionality", () => { + const plainDate1 = new Temporal.PlainDate(2021, 7, 26); + expect(Temporal.PlainDate.compare(plainDate1, plainDate1)).toBe(0); + const plainDate2 = new Temporal.PlainDate(2021, 7, 27); + expect(Temporal.PlainDate.compare(plainDate1, plainDate2)).toBe(-1); + expect(Temporal.PlainDate.compare(plainDate2, plainDate1)).toBe(1); + }); +});