From 511029807a1b88ef811f98056cda8d81c4a06c90 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 26 Nov 2024 10:51:45 -0500 Subject: [PATCH] LibJS: Implement Date.prototype.toTemporalInstant --- Libraries/LibJS/Runtime/CommonPropertyNames.h | 1 + Libraries/LibJS/Runtime/DatePrototype.cpp | 21 +++++++++++++++++++ Libraries/LibJS/Runtime/DatePrototype.h | 2 ++ .../Date/Date.prototype.toTemporalInstant.js | 15 +++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 Libraries/LibJS/Tests/builtins/Date/Date.prototype.toTemporalInstant.js diff --git a/Libraries/LibJS/Runtime/CommonPropertyNames.h b/Libraries/LibJS/Runtime/CommonPropertyNames.h index 9960c83cc85..2a271c5bad0 100644 --- a/Libraries/LibJS/Runtime/CommonPropertyNames.h +++ b/Libraries/LibJS/Runtime/CommonPropertyNames.h @@ -538,6 +538,7 @@ namespace JS { P(toSpliced) \ P(toString) \ P(total) \ + P(toTemporalInstant) \ P(toTimeString) \ P(toUpperCase) \ P(toUTCString) \ diff --git a/Libraries/LibJS/Runtime/DatePrototype.cpp b/Libraries/LibJS/Runtime/DatePrototype.cpp index 14740241eb8..fd31423bff3 100644 --- a/Libraries/LibJS/Runtime/DatePrototype.cpp +++ b/Libraries/LibJS/Runtime/DatePrototype.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -86,6 +87,8 @@ void DatePrototype::initialize(Realm& realm) define_native_function(realm, vm.names.toTimeString, to_time_string, 0, attr); define_native_function(realm, vm.names.toUTCString, to_utc_string, 0, attr); + define_native_function(realm, vm.names.toTemporalInstant, to_temporal_instant, 0, attr); + define_native_function(realm, vm.names.getYear, get_year, 0, attr); define_native_function(realm, vm.names.setYear, set_year, 1, attr); @@ -1221,6 +1224,24 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::symbol_to_primitive) return TRY(this_value.as_object().ordinary_to_primitive(try_first)); } +// 14.8.1 Date.prototype.toTemporalInstant ( ), https://tc39.es/proposal-temporal/#sec-date.prototype.totemporalinstant +JS_DEFINE_NATIVE_FUNCTION(DatePrototype::to_temporal_instant) +{ + // 1. Let dateObject be the this value. + // 2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]). + auto date_object = TRY(typed_this_value(vm)); + + // 3. Let t be dateObject.[[DateValue]]. + auto time = date_object->date_value(); + + // 4. Let ns be ? NumberToBigInt(t) × ℤ(10**6). + auto nanoseconds = TRY(number_to_bigint(vm, Value { time })); + nanoseconds = BigInt::create(vm, nanoseconds->big_integer().multiplied_by(Temporal::NANOSECONDS_PER_MILLISECOND)); + + // 5. Return ! CreateTemporalInstant(ns). + return MUST(Temporal::create_temporal_instant(vm, nanoseconds)); +} + // B.2.4.1 Date.prototype.getYear ( ), https://tc39.es/ecma262/#sec-date.prototype.getyear JS_DEFINE_NATIVE_FUNCTION(DatePrototype::get_year) { diff --git a/Libraries/LibJS/Runtime/DatePrototype.h b/Libraries/LibJS/Runtime/DatePrototype.h index c55f5dd4536..bb28e970806 100644 --- a/Libraries/LibJS/Runtime/DatePrototype.h +++ b/Libraries/LibJS/Runtime/DatePrototype.h @@ -65,6 +65,8 @@ private: JS_DECLARE_NATIVE_FUNCTION(to_time_string); JS_DECLARE_NATIVE_FUNCTION(to_utc_string); + JS_DECLARE_NATIVE_FUNCTION(to_temporal_instant); + JS_DECLARE_NATIVE_FUNCTION(get_year); JS_DECLARE_NATIVE_FUNCTION(set_year); JS_DECLARE_NATIVE_FUNCTION(to_gmt_string); diff --git a/Libraries/LibJS/Tests/builtins/Date/Date.prototype.toTemporalInstant.js b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.toTemporalInstant.js new file mode 100644 index 00000000000..6e3fc6691b6 --- /dev/null +++ b/Libraries/LibJS/Tests/builtins/Date/Date.prototype.toTemporalInstant.js @@ -0,0 +1,15 @@ +describe("correct behavior", () => { + test("basic functionality", () => { + const date = new Date("2021-07-09T01:36:00Z"); + const instant = date.toTemporalInstant(); + expect(instant.epochMilliseconds).toBe(1625794560000); + }); +}); + +describe("errors", () => { + test("this value must be a Date object", () => { + expect(() => { + Date.prototype.toTemporalInstant.call(123); + }).toThrowWithMessage(TypeError, "Not an object of type Date"); + }); +});