Przeglądaj źródła

LibJS: Implement Temporal.Now.zonedDateTime()

Linus Groh 4 lat temu
rodzic
commit
36c79c2989

+ 2 - 1
Userland/Libraries/LibJS/Runtime/CommonPropertyNames.h

@@ -413,7 +413,8 @@ namespace JS {
     P(withPlainDate)                         \
     P(writable)                              \
     P(year)                                  \
-    P(years)
+    P(years)                                 \
+    P(zonedDateTime)
 
 struct CommonPropertyNames {
     PropertyName and_ { "and", PropertyName::StringMayBeNumber::No };

+ 46 - 1
Userland/Libraries/LibJS/Runtime/Temporal/Now.cpp

@@ -13,6 +13,7 @@
 #include <LibJS/Runtime/Temporal/PlainDateTime.h>
 #include <LibJS/Runtime/Temporal/PlainTime.h>
 #include <LibJS/Runtime/Temporal/TimeZone.h>
+#include <LibJS/Runtime/Temporal/ZonedDateTime.h>
 #include <time.h>
 
 namespace JS::Temporal {
@@ -37,6 +38,7 @@ void Now::initialize(GlobalObject& global_object)
     define_native_function(vm.names.instant, instant, 0, attr);
     define_native_function(vm.names.plainDateTime, plain_date_time, 1, attr);
     define_native_function(vm.names.plainDateTimeISO, plain_date_time_iso, 0, attr);
+    define_native_function(vm.names.zonedDateTime, zoned_date_time, 1, attr);
     define_native_function(vm.names.plainDate, plain_date, 1, attr);
     define_native_function(vm.names.plainDateISO, plain_date_iso, 0, attr);
     define_native_function(vm.names.plainTimeISO, plain_time_iso, 0, attr);
@@ -78,6 +80,16 @@ JS_DEFINE_NATIVE_FUNCTION(Now::plain_date_time_iso)
     return system_date_time(global_object, temporal_time_zone_like, calendar);
 }
 
+// 2.2.5 Temporal.Now.zonedDateTime ( calendar [ , temporalTimeZoneLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.now.zoneddatetime
+JS_DEFINE_NATIVE_FUNCTION(Now::zoned_date_time)
+{
+    auto calendar = vm.argument(0);
+    auto temporal_time_zone_like = vm.argument(1);
+
+    // 1. Return ? SystemZonedDateTime(temporalTimeZoneLike, calendar).
+    return system_zoned_date_time(global_object, temporal_time_zone_like, calendar);
+}
+
 // 2.2.7 Temporal.Now.plainDate ( calendar [ , temporalTimeZoneLike ] ), https://tc39.es/proposal-temporal/#sec-temporal.now.plaindate
 JS_DEFINE_NATIVE_FUNCTION(Now::plain_date)
 {
@@ -180,7 +192,9 @@ PlainDateTime* system_date_time(GlobalObject& global_object, Value temporal_time
     if (temporal_time_zone_like.is_undefined()) {
         // a. Let timeZone be ! SystemTimeZone().
         time_zone = system_time_zone(global_object);
-    } else {
+    }
+    // 2. Else,
+    else {
         // a. Let timeZone be ? ToTemporalTimeZone(temporalTimeZoneLike).
         time_zone = to_temporal_time_zone(global_object, temporal_time_zone_like);
         if (vm.exception())
@@ -199,4 +213,35 @@ PlainDateTime* system_date_time(GlobalObject& global_object, Value temporal_time
     return builtin_time_zone_get_plain_date_time_for(global_object, time_zone, *instant, *calendar);
 }
 
+// 2.3.5 SystemZonedDateTime ( temporalTimeZoneLike, calendarLike )
+ZonedDateTime* system_zoned_date_time(GlobalObject& global_object, Value temporal_time_zone_like, Value calendar_like)
+{
+    auto& vm = global_object.vm();
+    Object* time_zone;
+
+    // 1. If temporalTimeZoneLike is undefined, then
+    if (temporal_time_zone_like.is_undefined()) {
+        // a. Let timeZone be ! SystemTimeZone().
+        time_zone = system_time_zone(global_object);
+    }
+    // 2. Else,
+    else {
+        // a. Let timeZone be ? ToTemporalTimeZone(temporalTimeZoneLike).
+        time_zone = to_temporal_time_zone(global_object, temporal_time_zone_like);
+        if (vm.exception())
+            return {};
+    }
+
+    // 3. Let calendar be ? ToTemporalCalendar(calendarLike).
+    auto* calendar = to_temporal_calendar(global_object, calendar_like);
+    if (vm.exception())
+        return {};
+
+    // 4. Let ns be ! SystemUTCEpochNanoseconds().
+    auto* ns = system_utc_epoch_nanoseconds(global_object);
+
+    // 5. Return ? CreateTemporalZonedDateTime(ns, timeZone, calendar).
+    return create_temporal_zoned_date_time(global_object, *ns, *time_zone, *calendar);
+}
+
 }

+ 2 - 0
Userland/Libraries/LibJS/Runtime/Temporal/Now.h

@@ -23,6 +23,7 @@ private:
     JS_DECLARE_NATIVE_FUNCTION(instant);
     JS_DECLARE_NATIVE_FUNCTION(plain_date_time);
     JS_DECLARE_NATIVE_FUNCTION(plain_date_time_iso);
+    JS_DECLARE_NATIVE_FUNCTION(zoned_date_time);
     JS_DECLARE_NATIVE_FUNCTION(plain_date);
     JS_DECLARE_NATIVE_FUNCTION(plain_date_iso);
     JS_DECLARE_NATIVE_FUNCTION(plain_time_iso);
@@ -32,5 +33,6 @@ TimeZone* system_time_zone(GlobalObject&);
 BigInt* system_utc_epoch_nanoseconds(GlobalObject&);
 Instant* system_instant(GlobalObject&);
 PlainDateTime* system_date_time(GlobalObject&, Value temporal_time_zone_like, Value calendar_like);
+ZonedDateTime* system_zoned_date_time(GlobalObject&, Value temporal_time_zone_like, Value calendar_like);
 
 }

+ 21 - 0
Userland/Libraries/LibJS/Tests/builtins/Temporal/Now/Now.zonedDateTime.js

@@ -0,0 +1,21 @@
+describe("correct behavior", () => {
+    test("length is 1", () => {
+        expect(Temporal.Now.zonedDateTime).toHaveLength(1);
+    });
+
+    test("basic functionality", () => {
+        const calendar = new Temporal.Calendar("iso8601");
+        const zonedDateTime = Temporal.Now.zonedDateTime(calendar);
+        expect(zonedDateTime).toBeInstanceOf(Temporal.ZonedDateTime);
+        expect(zonedDateTime.calendar).toBe(calendar);
+    });
+
+    test("with time zone", () => {
+        const calendar = new Temporal.Calendar("iso8601");
+        const timeZone = new Temporal.TimeZone("UTC");
+        const zonedDateTime = Temporal.Now.zonedDateTime(calendar, timeZone);
+        expect(zonedDateTime).toBeInstanceOf(Temporal.ZonedDateTime);
+        expect(zonedDateTime.calendar).toBe(calendar);
+        expect(zonedDateTime.timeZone).toBe(timeZone);
+    });
+});